Skip to content

Commit 130914f

Browse files
committed
Fix ordering for possessive repeat.
1 parent f61a7e0 commit 130914f

File tree

2 files changed

+11
-6
lines changed

2 files changed

+11
-6
lines changed

Diff for: include/ctre/evaluation.hpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c
287287

288288
template <typename R, typename Iterator, typename EndIterator, typename... Tail>
289289
constexpr CTRE_FORCE_INLINE R ordered_evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<assert_begin, Tail...>) noexcept {
290-
if (begin != current) { //TODO I'm really not sure how to handle this.
291-
// Problematic pattern: "x*+^[a-z]*" (words that don't start with x)
292-
return not_matched;
290+
if (begin != current) {
291+
captures.mask_elg({0,1,1});
292+
return captures;
293293
}
294294
return ordered_evaluate(begin, current, end, captures, ctll::list<Tail...>());
295295
}
@@ -406,7 +406,6 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c
406406

407407
template <typename R, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail>
408408
constexpr CTRE_FORCE_INLINE R ordered_evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<possessive_repeat<A,B,Content...>, Tail...>) noexcept {
409-
//TODO this doesn't work yet!
410409
// A..B
411410
size_t i{0};
412411
for (; i < A && (A != 0); ++i) {
@@ -419,12 +418,18 @@ constexpr CTRE_FORCE_INLINE R ordered_evaluate(const Iterator begin, Iterator cu
419418

420419
for (; (i < B) || (B == 0); ++i) {
421420
// try as many of inner as possible and then try outer once
421+
422+
// I have to mask this ordering beforehand, as we can't backtrack later.
423+
// This basically throws away the usual runtime benefits of a possessive repeat.
424+
auto outer_result = ordered_evaluate(begin, current, end, captures, ctll::list<Tail...>());
425+
captures.mask_lg(outer_result);
426+
422427
auto inner_result = ordered_evaluate(begin, current, end, captures, ctll::list<sequence<Content...>, end_cycle_mark>());
423428
captures.mask_lg(inner_result);
424429
if (inner_result) {
425430
current = inner_result.get_end_position();
426431
} else {
427-
return ordered_evaluate(begin, current, end, captures, ctll::list<Tail...>());
432+
return outer_result;
428433
}
429434
}
430435

Diff for: test_ordering.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ std::ostream& operator<<(std::ostream& os, ctre::partial_ordering ord) {
1919

2020
int main(int argc, char ** argv) {
2121
using namespace ctre::literals;
22-
constexpr auto re = "(?<ab>[b-c])\\g{ab}"_ctre;
22+
constexpr auto re = "x*+^[a-y]+"_ctre;
2323

2424
std::cout << ctre::partial_ordering(re.match(argv[1])) << std::endl;
2525
std::cout << ctre::partial_ordering(re.ordered_match(argv[1])) << std::endl;

0 commit comments

Comments
 (0)