diff --git a/include/ctll/list.hpp b/include/ctll/list.hpp index ae1fd0c3..a04ed512 100644 --- a/include/ctll/list.hpp +++ b/include/ctll/list.hpp @@ -47,6 +47,14 @@ template constexpr auto pop_and_get_front(empty_list, T template constexpr auto front(list, T = T()) noexcept -> Head { return {}; } template constexpr auto front(empty_list, T = T()) noexcept -> T { return {}; } +// rotate list +template struct rotate_item { + template friend constexpr auto operator+(list, rotate_item) noexcept -> list { return {}; } +}; + +template constexpr auto rotate(list) -> decltype((list<>{} + ... + rotate_item{})) { + return {}; +} // set operations template struct item_matcher { diff --git a/include/ctre/actions/look.inc.hpp b/include/ctre/actions/look.inc.hpp index 451ecaa6..8786a775 100644 --- a/include/ctre/actions/look.inc.hpp +++ b/include/ctre/actions/look.inc.hpp @@ -31,4 +31,38 @@ template static const return pcre_context{ctll::list, Ts...>(), pcre_parameters()}; } +// LOOKBEHIND + +// lookbehind positive start +template static constexpr auto apply(pcre::start_lookbehind_positive, ctll::term, pcre_context, pcre_parameters>) { + return pcre_context{ctll::list>, Ts...>(), pcre_parameters()}; +} + +// lookbehind positive end +template static constexpr auto apply(pcre::look_finish, ctll::term, pcre_context>, Ts...>, pcre_parameters>) { + return pcre_context{ctll::list, Ts...>(), pcre_parameters()}; +} + +// lookbehind positive end (sequence) +template static constexpr auto apply(pcre::look_finish, ctll::term, pcre_context, look_start>, Ts...>, pcre_parameters>) { + using my_lookbehind = decltype(ctre::convert_to_basic_list(ctll::rotate(ctll::list{}))); + return pcre_context{ctll::list(), pcre_parameters()}; +} + +// lookbehind negative start +template static constexpr auto apply(pcre::start_lookbehind_negative, ctll::term, pcre_context, pcre_parameters>) { + return pcre_context{ctll::list>, Ts...>(), pcre_parameters()}; +} + +// lookbehind negative end +template static constexpr auto apply(pcre::look_finish, ctll::term, pcre_context>, Ts...>, pcre_parameters>) { + return pcre_context{ctll::list, Ts...>(), pcre_parameters()}; +} + +// lookbehind negative end (sequence) +template static constexpr auto apply(pcre::look_finish, ctll::term, pcre_context, look_start>, Ts...>, pcre_parameters>) { + using my_lookbehind = decltype(ctre::convert_to_basic_list(ctll::rotate(ctll::list{}))); + return pcre_context{ctll::list(), pcre_parameters()}; +} + #endif diff --git a/include/ctre/atoms.hpp b/include/ctre/atoms.hpp index 411b099a..bdd06b05 100644 --- a/include/ctre/atoms.hpp +++ b/include/ctre/atoms.hpp @@ -13,6 +13,7 @@ struct start_mark { }; struct end_mark { }; struct end_cycle_mark { }; struct end_lookahead_mark { }; +struct end_lookbehind_mark { }; template struct numeric_mark { }; struct any { }; @@ -51,6 +52,9 @@ template struct look_start { }; template struct lookahead_positive { }; template struct lookahead_negative { }; +template struct lookbehind_positive { }; +template struct lookbehind_negative { }; + struct atomic_start { }; template struct atomic_group { }; diff --git a/include/ctre/evaluation.hpp b/include/ctre/evaluation.hpp index 99bd0b75..35821736 100644 --- a/include/ctre/evaluation.hpp +++ b/include/ctre/evaluation.hpp @@ -42,38 +42,38 @@ constexpr bool is_bidirectional(const std::bidirectional_iterator_tag &) { retur constexpr bool is_bidirectional(...) { return false; } // sink for making the errors shorter -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, flags, R, ...) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ...) noexcept { return not_matched; } // if we found "accept" object on stack => ACCEPT -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, flags, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list) noexcept { return captures.matched(); } // if we found "reject" object on stack => REJECT -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, flags, R, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ctll::list) noexcept { return not_matched; } // mark start of outer capture -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { return evaluate(begin, current, last, f, captures.set_start_mark(current), ctll::list()); } // mark end of outer capture -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { return evaluate(begin, current, last, f, captures.set_end_mark(current), ctll::list()); } // mark end of cycle -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator current, const EndIterator, [[maybe_unused]] const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator current, const EndIterator, [[maybe_unused]] const flags & f, R captures, ctll::list) noexcept { if (cannot_be_empty_match(f)) { return not_matched; } @@ -83,16 +83,16 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator current, const E // matching everything which behave as a one character matcher -template ::template value())>)>> -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template ::template value())>)>> +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (current == last) return not_matched; if (!CharacterLike::match_char(*current, f)) return not_matched; return evaluate(begin, ++current, last, consumed_something(f), captures, ctll::list()); } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (current == last) return not_matched; if (multiline_mode(f)) { @@ -107,8 +107,8 @@ template constexpr CTR return ((current != last && character::match_char(*current++, f)) && ... && true); } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...>) noexcept { if (!match_string(current, last, f)) { return not_matched; } @@ -117,8 +117,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // matching select in patterns -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { if (auto r = evaluate(begin, current, last, f, captures, ctll::list())) { return r; } else { @@ -126,15 +126,15 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, flags, R, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R, ctll::list, Tail...>) noexcept { // no previous option was matched => REJECT return not_matched; } // matching sequence in patterns -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { if constexpr (sizeof...(TailContent) > 0) { return evaluate(begin, current, last, f, captures, ctll::list, Tail...>()); } else { @@ -143,30 +143,30 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // matching empty in patterns -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { return evaluate(begin, current, last, f, captures, ctll::list()); } // matching asserts -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (begin != current) { return not_matched; } return evaluate(begin, current, last, f, captures, ctll::list()); } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (last != current) { return not_matched; } return evaluate(begin, current, last, f, captures, ctll::list()); } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (multiline_mode(f)) { if (last == current) { return evaluate(begin, current, last, f, captures, ctll::list()); @@ -183,8 +183,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (multiline_mode(f)) { if (begin == current) { return evaluate(begin, current, last, f, captures, ctll::list()); @@ -201,8 +201,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } } -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list) noexcept { if (multiline_mode(f)) { if (last == current) { return evaluate(begin, current, last, f, captures, ctll::list()); @@ -226,8 +226,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // matching boundary -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { // reason why I need bidirectional iterators or some clever hack bool before = false; @@ -248,8 +248,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // matching not_boundary -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { // reason why I need bidirectional iterators or some clever hack bool before = false; @@ -270,8 +270,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // lazy repeat -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...>) noexcept { if constexpr (B != 0 && A > B) { return not_matched; @@ -318,8 +318,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // possessive repeat -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...>) noexcept { if constexpr ((B != 0) && (A > B)) { return not_matched; @@ -344,11 +344,11 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // (gready) repeat -template +template #ifdef CTRE_MSVC_GREEDY_WORKAROUND -constexpr inline void evaluate_recursive(R & result, size_t i, const Iterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...> stack) noexcept { +constexpr inline void evaluate_recursive(R & result, size_t i, const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...> stack) noexcept { #else -constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...> stack) noexcept { +constexpr inline R evaluate_recursive(size_t i, const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, ctll::list, Tail...> stack) noexcept { #endif if (less_than_or_infinite(i)) { @@ -384,8 +384,8 @@ constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator c // (greedy) repeat -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, [[maybe_unused]] ctll::list, Tail...> stack) { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, [[maybe_unused]] const flags & f, R captures, [[maybe_unused]] ctll::list, Tail...> stack) { if constexpr ((B != 0) && (A > B)) { return not_matched; @@ -422,20 +422,20 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // capture (numeric ID) -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { return evaluate(begin, current, last, f, captures.template start_capture(current), ctll::list, numeric_mark, Tail...>()); } // capture end mark (numeric and string ID) -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { return evaluate(begin, current, last, f, captures.template end_capture(current), ctll::list()); } // capture (string ID) -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { return evaluate(begin, current, last, f, captures.template start_capture(current), ctll::list, numeric_mark, Tail...>()); } @@ -458,8 +458,8 @@ template constexpr CTRE_FORCE_INLINE s } // backreference with name -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { if (const auto ref = captures.template get()) { if (auto result = match_against_range(current, last, ref.begin(), ref.end(), f); result.match) { @@ -470,8 +470,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // backreference -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { if (const auto ref = captures.template get()) { if (auto result = match_against_range(current, last, ref.begin(), ref.end(), f); result.match) { @@ -482,15 +482,21 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // end of lookahead -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator, Iterator, const EndIterator, flags, R captures, ctll::list) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list) noexcept { + // TODO check interaction with non-empty flag + return captures.matched(); +} + +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator, Iterator, const EndIterator, flags, R captures, ctll::list) noexcept { // TODO check interaction with non-empty flag return captures.matched(); } // lookahead positive -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { if (auto lookahead_result = evaluate(begin, current, last, f, captures, ctll::list, end_lookahead_mark>())) { captures = lookahead_result.unmatch(); @@ -501,8 +507,8 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } // lookahead negative -template -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { if (auto lookahead_result = evaluate(begin, current, last, f, captures, ctll::list, end_lookahead_mark>())) { return not_matched; @@ -511,6 +517,39 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c } } +// lookbehind positive +constexpr bool is_at_least_bidirectional(std::input_iterator_tag) { + return false; +} + +constexpr bool is_at_least_bidirectional(std::bidirectional_iterator_tag) { + return true; +} + +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { + static_assert(is_at_least_bidirectional(typename std::iterator_traits::iterator_category{}), "to use lookbehind you must provide bi-directional iterator"); + + if (auto lookbehind_result = evaluate(std::make_reverse_iterator(last), std::make_reverse_iterator(current), std::make_reverse_iterator(begin), f, captures, ctll::list, end_lookbehind_mark>())) { + captures = lookbehind_result.unmatch(); + return evaluate(begin, current, last, f, captures, ctll::list()); + } else { + return not_matched; + } +} + +// lookbehind negative +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { + static_assert(is_at_least_bidirectional(typename std::iterator_traits::iterator_category{}), "to use negative lookbehind you must provide bi-directional iterator"); + + if (auto lookbehind_result = evaluate(std::make_reverse_iterator(last), std::make_reverse_iterator(current), std::make_reverse_iterator(begin), f, captures, ctll::list, end_lookbehind_mark>())) { + return not_matched; + } else { + return evaluate(begin, current, last, f, captures, ctll::list()); + } +} + } diff --git a/include/ctre/first.hpp b/include/ctre/first.hpp index 82e07fc3..024c6dd3 100644 --- a/include/ctre/first.hpp +++ b/include/ctre/first.hpp @@ -161,6 +161,18 @@ constexpr auto first(ctll::list, ctll::list{}; } +// lookbehind_negative TODO fixme +template +constexpr auto first(ctll::list, ctll::list, Tail...>) noexcept { + return ctll::list{}; +} + +// lookbehind_positive +template +constexpr auto first(ctll::list, ctll::list, Tail...>) noexcept { + return ctll::list{}; +} + // lookahead_negative TODO fixme template constexpr auto first(ctll::list, ctll::list, Tail...>) noexcept { diff --git a/include/ctre/pcre.gram b/include/ctre/pcre.gram index 592401b1..78b28d02 100644 --- a/include/ctre/pcre.gram +++ b/include/ctre/pcre.gram @@ -67,10 +67,12 @@ number2->epsilon | num,[push_number], preblock->open,[prepare_capture], block->,[make_capture],close -block->questionmark,[reset_capture],angle_close,[start_atomic],,[make_atomic],close -block->questionmark,[reset_capture],equal_sign,[start_lookahead_positive],,[look_finish],close -block->questionmark,[reset_capture],exclamation_mark,[start_lookahead_negative],,[look_finish],close -block->questionmark,[reset_capture],colon,,close +block->questionmark,angle_close,[reset_capture],[start_atomic],,[make_atomic],close +block->questionmark,equal_sign,[reset_capture],[start_lookahead_positive],,[look_finish],close +block->questionmark,angle_open,equal_sign,[reset_capture],[start_lookbehind_positive],,[look_finish],close +block->questionmark,exclamation_mark,[reset_capture],[start_lookahead_negative],,[look_finish],close +block->questionmark,angle_open,exclamation_mark,[reset_capture],[start_lookbehind_negative],,[look_finish],close +block->questionmark,colon,[reset_capture],,close block->questionmark,angle_open,,angle_close,,[make_capture_with_name],close block_name->alpha_characters,[push_name], diff --git a/include/ctre/pcre.hpp b/include/ctre/pcre.hpp index 71347150..0f5a3a0d 100644 --- a/include/ctre/pcre.hpp +++ b/include/ctre/pcre.hpp @@ -16,7 +16,6 @@ struct pcre { struct backslash_range {}; struct block {}; struct block_name2 {}; - struct block_name {}; struct c {}; struct class_named_name {}; struct content2 {}; @@ -38,6 +37,7 @@ struct pcre { struct number2 {}; struct number {}; struct o {}; + struct p {}; struct property_name2 {}; struct property_name {}; struct property_value2 {}; @@ -129,15 +129,17 @@ struct pcre { struct start_atomic: ctll::action {}; struct start_lookahead_negative: ctll::action {}; struct start_lookahead_positive: ctll::action {}; + struct start_lookbehind_negative: ctll::action {}; + struct start_lookbehind_positive: ctll::action {}; // (q)LL1 function: - using _others = ctll::neg_set<'!','$','\x28','\x29','*','+',',','-','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','0','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>; + using _others = ctll::neg_set<'!','$','\x28','\x29','*','+',',','-','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','0','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>; static constexpr auto rule(s, ctll::term<'\\'>) -> ctll::push; static constexpr auto rule(s, ctll::term<'['>) -> ctll::push; static constexpr auto rule(s, ctll::term<'\x28'>) -> ctll::push; static constexpr auto rule(s, ctll::term<'^'>) -> ctll::push; static constexpr auto rule(s, ctll::term<'$'>) -> ctll::push; - static constexpr auto rule(s, ctll::set<'!',',','-','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','\"',']','0','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(s, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(s, _others) -> ctll::push; static constexpr auto rule(s, ctll::term<'.'>) -> ctll::push; static constexpr auto rule(s, ctll::term<'|'>) -> ctll::push; @@ -149,7 +151,7 @@ struct pcre { static constexpr auto rule(a, ctll::term<'\x28'>) -> ctll::push; static constexpr auto rule(a, ctll::term<'^'>) -> ctll::push; static constexpr auto rule(a, ctll::term<'$'>) -> ctll::push; - static constexpr auto rule(a, ctll::set<'!',',','-','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','\"',']','0','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(a, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(a, _others) -> ctll::push; static constexpr auto rule(a, ctll::term<'.'>) -> ctll::push; static constexpr auto rule(a, ctll::term<'\x29'>) -> ctll::push; @@ -207,7 +209,7 @@ struct pcre { static constexpr auto rule(block, ctll::term<'\x28'>) -> ctll::push>; static constexpr auto rule(block, ctll::term<'^'>) -> ctll::push>; static constexpr auto rule(block, ctll::term<'$'>) -> ctll::push>; - static constexpr auto rule(block, ctll::set<'!',',','-','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','\"',']','0','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push>; + static constexpr auto rule(block, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push>; static constexpr auto rule(block, _others) -> ctll::push>; static constexpr auto rule(block, ctll::term<'.'>) -> ctll::push>; static constexpr auto rule(block, ctll::term<'|'>) -> ctll::push>; @@ -217,11 +219,9 @@ struct pcre { static constexpr auto rule(block_name2, ctll::set<'>','\x7D'>) -> ctll::epsilon; static constexpr auto rule(block_name2, ctll::set<'0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; - static constexpr auto rule(block_name, ctll::set<'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'>) -> ctll::push; - static constexpr auto rule(c, ctll::term<'['>) -> ctll::push, i, range, set_start, set2b, set_make, ctll::term<']'>>; static constexpr auto rule(c, ctll::term<'\\'>) -> ctll::push>; - static constexpr auto rule(c, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','0','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push>; + static constexpr auto rule(c, ctll::set<'!','0','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push>; static constexpr auto rule(c, _others) -> ctll::push>; static constexpr auto rule(c, ctll::term<'^'>) -> ctll::push>; static constexpr auto rule(c, ctll::set<'-',']'>) -> ctll::reject; @@ -247,7 +247,7 @@ struct pcre { static constexpr auto rule(content, ctll::term<'\x28'>) -> ctll::push; static constexpr auto rule(content, ctll::term<'^'>) -> ctll::push; static constexpr auto rule(content, ctll::term<'$'>) -> ctll::push; - static constexpr auto rule(content, ctll::set<'!',',','-','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','\"',']','0','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(content, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(content, _others) -> ctll::push; static constexpr auto rule(content, ctll::term<'.'>) -> ctll::push; static constexpr auto rule(content, ctll::set<'\x29','*','+','?','\x7B','|','\x7D'>) -> ctll::reject; @@ -257,18 +257,18 @@ struct pcre { static constexpr auto rule(content_in_capture, ctll::term<'\x28'>) -> ctll::push; static constexpr auto rule(content_in_capture, ctll::term<'^'>) -> ctll::push; static constexpr auto rule(content_in_capture, ctll::term<'$'>) -> ctll::push; - static constexpr auto rule(content_in_capture, ctll::set<'!',',','-','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','\"',']','0','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(content_in_capture, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(content_in_capture, _others) -> ctll::push; static constexpr auto rule(content_in_capture, ctll::term<'.'>) -> ctll::push; static constexpr auto rule(content_in_capture, ctll::term<'|'>) -> ctll::push; static constexpr auto rule(content_in_capture, ctll::term<'\x29'>) -> ctll::push; static constexpr auto rule(content_in_capture, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject; - static constexpr auto rule(d, ctll::term<'<'>) -> ctll::push'>, content_in_capture, make_capture_with_name, ctll::term<'\x29'>>; - static constexpr auto rule(d, ctll::term<':'>) -> ctll::push>; - static constexpr auto rule(d, ctll::term<'>'>) -> ctll::push>; - static constexpr auto rule(d, ctll::term<'!'>) -> ctll::push>; - static constexpr auto rule(d, ctll::term<'='>) -> ctll::push>; + static constexpr auto rule(d, ctll::term<'<'>) -> ctll::push; + static constexpr auto rule(d, ctll::term<':'>) -> ctll::push>; + static constexpr auto rule(d, ctll::term<'>'>) -> ctll::push>; + static constexpr auto rule(d, ctll::term<'!'>) -> ctll::push>; + static constexpr auto rule(d, ctll::term<'='>) -> ctll::push>; static constexpr auto rule(e, ctll::term<'d'>) -> ctll::push; static constexpr auto rule(e, ctll::term<'h'>) -> ctll::push; @@ -319,7 +319,7 @@ struct pcre { static constexpr auto rule(f, ctll::term<'t'>) -> ctll::push; static constexpr auto rule(g, ctll::term<'s'>) -> ctll::push, ctll::term<'i'>, ctll::term<'i'>, class_named_ascii>; - static constexpr auto rule(g, ctll::term<'l'>) -> ctll::push; + static constexpr auto rule(g, ctll::term<'l'>) -> ctll::push; static constexpr auto rule(h, ctll::term<'r'>) -> ctll::push, ctll::term<'n'>, ctll::term<'t'>, class_named_print>; static constexpr auto rule(h, ctll::term<'u'>) -> ctll::push, ctll::term<'c'>, ctll::term<'t'>, class_named_punct>; @@ -341,7 +341,7 @@ struct pcre { static constexpr auto rule(i, ctll::term<'p'>) -> ctll::push, ctll::term<']'>>; static constexpr auto rule(j, ctll::term<'\\'>) -> ctll::push; - static constexpr auto rule(j, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','0','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(j, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','0','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(j, _others) -> ctll::push; static constexpr auto rule(j, ctll::set<'-','[',']'>) -> ctll::reject; @@ -355,7 +355,7 @@ struct pcre { static constexpr auto rule(m, ctll::term<'-'>) -> ctll::push, make_relative_back_reference>; static constexpr auto rule(m, ctll::set<'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'>) -> ctll::push, make_back_reference>; - static constexpr auto rule(mod, ctll::set<'!','$','\x28','\x29',',','-','.','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|','0','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon; + static constexpr auto rule(mod, ctll::set<'!','$','\x28','\x29',',','-','.','/','0',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon; static constexpr auto rule(mod, ctll::epsilon) -> ctll::epsilon; static constexpr auto rule(mod, _others) -> ctll::epsilon; static constexpr auto rule(mod, ctll::term<'?'>) -> ctll::push; @@ -370,8 +370,12 @@ struct pcre { static constexpr auto rule(number, ctll::set<'0','1','2','3','4','5','6','7','8','9'>) -> ctll::push; - static constexpr auto rule(o, ctll::term<'p'>) -> ctll::push, ctll::term<'a'>, class_named_alpha>; - static constexpr auto rule(o, ctll::term<'n'>) -> ctll::push, ctll::term<'m'>, class_named_alnum>; + static constexpr auto rule(o, ctll::set<'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'>) -> ctll::push'>, content_in_capture, make_capture_with_name, ctll::term<'\x29'>>; + static constexpr auto rule(o, ctll::term<'!'>) -> ctll::push>; + static constexpr auto rule(o, ctll::term<'='>) -> ctll::push>; + + static constexpr auto rule(p, ctll::term<'p'>) -> ctll::push, ctll::term<'a'>, class_named_alpha>; + static constexpr auto rule(p, ctll::term<'n'>) -> ctll::push, ctll::term<'m'>, class_named_alnum>; static constexpr auto rule(property_name2, ctll::term<'\x7D'>) -> ctll::epsilon; static constexpr auto rule(property_name2, ctll::term<'='>) -> ctll::push; @@ -384,12 +388,12 @@ struct pcre { static constexpr auto rule(property_value, ctll::set<'0','.','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; - static constexpr auto rule(range, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','0','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon; + static constexpr auto rule(range, ctll::set<'!','$','\x28','\x29','*','+',',','.','/','0',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon; static constexpr auto rule(range, ctll::epsilon) -> ctll::epsilon; static constexpr auto rule(range, _others) -> ctll::epsilon; static constexpr auto rule(range, ctll::term<'-'>) -> ctll::push; - static constexpr auto rule(repeat, ctll::set<'!','$','\x28','\x29',',','-','.','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|','0','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon; + static constexpr auto rule(repeat, ctll::set<'!','$','\x28','\x29',',','-','.','/','0',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[','\\','\"',']','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|','1','2','3','4','5','6','7','8','9'>) -> ctll::epsilon; static constexpr auto rule(repeat, ctll::epsilon) -> ctll::epsilon; static constexpr auto rule(repeat, _others) -> ctll::epsilon; static constexpr auto rule(repeat, ctll::term<'?'>) -> ctll::push; @@ -401,14 +405,14 @@ struct pcre { static constexpr auto rule(set2a, ctll::term<']'>) -> ctll::epsilon; static constexpr auto rule(set2a, ctll::term<'['>) -> ctll::push, i, range, set_start, set2b>; static constexpr auto rule(set2a, ctll::term<'\\'>) -> ctll::push; - static constexpr auto rule(set2a, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','0','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(set2a, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','0','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(set2a, _others) -> ctll::push; static constexpr auto rule(set2a, ctll::term<'-'>) -> ctll::reject; static constexpr auto rule(set2b, ctll::term<']'>) -> ctll::epsilon; static constexpr auto rule(set2b, ctll::term<'['>) -> ctll::push, i, range, set_combine, set2b>; static constexpr auto rule(set2b, ctll::term<'\\'>) -> ctll::push; - static constexpr auto rule(set2b, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','0','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(set2b, ctll::set<'!','$','\x28','\x29','*','+',',','.','/',':','<','=','>','?','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"','^','0','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\x7B','|','\x7D','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(set2b, _others) -> ctll::push; static constexpr auto rule(set2b, ctll::term<'-'>) -> ctll::reject; @@ -419,7 +423,7 @@ struct pcre { static constexpr auto rule(string2, ctll::term<'\x28'>) -> ctll::push; static constexpr auto rule(string2, ctll::term<'^'>) -> ctll::push; static constexpr auto rule(string2, ctll::term<'$'>) -> ctll::push; - static constexpr auto rule(string2, ctll::set<'!',',','-','/',':','<','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','\"',']','0','U','V','W','X','Y','Z','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; + static constexpr auto rule(string2, ctll::set<'!',',','/',':','<','0','-','=','>','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\"',']','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9'>) -> ctll::push; static constexpr auto rule(string2, _others) -> ctll::push; static constexpr auto rule(string2, ctll::term<'.'>) -> ctll::push; static constexpr auto rule(string2, ctll::set<'*','+','?','\x7B','\x7D'>) -> ctll::reject; diff --git a/include/ctre/pcre_actions.hpp b/include/ctre/pcre_actions.hpp index c9536b2b..bfef1eda 100644 --- a/include/ctre/pcre_actions.hpp +++ b/include/ctre/pcre_actions.hpp @@ -2,8 +2,7 @@ #define CTRE__PCRE_ACTIONS__HPP #include "pcre.hpp" -#include "atoms.hpp" -#include "atoms_unicode.hpp" +#include "rotate.hpp" #include "id.hpp" #include #include diff --git a/include/ctre/rotate.hpp b/include/ctre/rotate.hpp new file mode 100644 index 00000000..2ecd6d32 --- /dev/null +++ b/include/ctre/rotate.hpp @@ -0,0 +1,99 @@ +#ifndef CTRE__ROTATE__HPP +#define CTRE__ROTATE__HPP + +#include "atoms.hpp" +#include "atoms_characters.hpp" +#include "atoms_unicode.hpp" + +namespace ctre { + +// helper functions +template auto convert_to_capture(ctll::list) -> capture; +template auto convert_to_named_capture(ctll::list) -> capture_with_name; +template