|
7 | 7 | #include "utility.hpp" |
8 | 8 | #include "return_type.hpp" |
9 | 9 | #include "find_captures.hpp" |
| 10 | +#include "first.hpp" |
10 | 11 |
|
11 | 12 | namespace ctre { |
12 | 13 |
|
@@ -219,23 +220,15 @@ constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, c |
219 | 220 | // possessive repeat |
220 | 221 | template <typename R, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> |
221 | 222 | constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<possessive_repeat<A,B,Content...>, Tail...>) noexcept { |
222 | | - // A..B |
223 | | - size_t i{0}; |
224 | | - for (; i < A && (A != 0); ++i) { |
225 | | - if (auto inner_result = evaluate(begin, current, end, captures, ctll::list<sequence<Content...>, end_cycle_mark>())) { |
226 | | - captures = inner_result.unmatch(); |
227 | | - current = inner_result.get_end_position(); |
228 | | - } else { |
229 | | - return not_matched; |
230 | | - } |
231 | | - } |
232 | | - |
233 | | - for (; (i < B) || (B == 0); ++i) { |
| 223 | + |
| 224 | + for (size_t i{0}; (i < B) || (B == 0); ++i) { |
234 | 225 | // try as many of inner as possible and then try outer once |
235 | 226 | if (auto inner_result = evaluate(begin, current, end, captures, ctll::list<sequence<Content...>, end_cycle_mark>())) { |
| 227 | + captures = inner_result.unmatch(); |
236 | 228 | current = inner_result.get_end_position(); |
237 | 229 | } else { |
238 | | - return evaluate(begin, current, end, captures, ctll::list<Tail...>()); |
| 230 | + if (i < A && (A != 0)) return not_matched; |
| 231 | + else return evaluate(begin, current, end, captures, ctll::list<Tail...>()); |
239 | 232 | } |
240 | 233 | } |
241 | 234 |
|
@@ -263,20 +256,43 @@ constexpr inline R evaluate_recursive(size_t i, const Iterator begin, Iterator c |
263 | 256 | return evaluate(begin, current, end, captures, ctll::list<Tail...>()); |
264 | 257 | } |
265 | 258 |
|
| 259 | + |
| 260 | +// (gready) repeat optimization |
| 261 | +// basic one, if you are at the end of RE, just change it into possessive |
| 262 | +// TODO do the same if there is no collision with rest of the RE |
266 | 263 | template <typename R, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> |
267 | | -constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<repeat<A,B,Content...>, Tail...> stack) { |
268 | | - // A..B |
269 | | - size_t i{0}; |
270 | | - for (; i < A && (A != 0); ++i) { |
271 | | - if (auto inner_result = evaluate(begin, current, end, captures, ctll::list<sequence<Content...>, end_cycle_mark>())) { |
272 | | - captures = inner_result.unmatch(); |
273 | | - current = inner_result.get_end_position(); |
274 | | - } else { |
275 | | - return not_matched; |
| 264 | +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, ctll::list<repeat<A,B,Content...>,assert_end, Tail...>) { |
| 265 | + return evaluate(begin, current, end, captures, ctll::list<possessive_repeat<A,B,Content...>, assert_end, Tail...>()); |
| 266 | +} |
| 267 | + |
| 268 | +template <typename... T> struct identify_type; |
| 269 | + |
| 270 | +// (greedy) repeat |
| 271 | +template <typename R, typename Iterator, typename EndIterator, size_t A, size_t B, typename... Content, typename... Tail> |
| 272 | +constexpr CTRE_FORCE_INLINE R evaluate(const Iterator begin, Iterator current, const EndIterator end, R captures, [[maybe_unused]] ctll::list<repeat<A,B,Content...>, Tail...> stack) { |
| 273 | + // check if it can be optimized |
| 274 | +#ifndef CTRE_DISABLE_GREEDY_OPT |
| 275 | + if constexpr (collides(calculate_first(Content{}...), calculate_first(Tail{}...))) { |
| 276 | +#endif |
| 277 | + // A..B |
| 278 | + size_t i{0}; |
| 279 | + for (; i < A && (A != 0); ++i) { |
| 280 | + if (auto inner_result = evaluate(begin, current, end, captures, ctll::list<sequence<Content...>, end_cycle_mark>())) { |
| 281 | + captures = inner_result.unmatch(); |
| 282 | + current = inner_result.get_end_position(); |
| 283 | + } else { |
| 284 | + return not_matched; |
| 285 | + } |
276 | 286 | } |
277 | | - } |
278 | 287 |
|
279 | | - return evaluate_recursive(i, begin, current, end, captures, stack); |
| 288 | + return evaluate_recursive(i, begin, current, end, captures, stack); |
| 289 | +#ifndef CTRE_DISABLE_GREEDY_OPT |
| 290 | + } else { |
| 291 | + // if there is no collision we can go possessive |
| 292 | + return evaluate(begin, current, end, captures, ctll::list<possessive_repeat<A,B,Content...>, Tail...>()); |
| 293 | + } |
| 294 | +#endif |
| 295 | + |
280 | 296 | } |
281 | 297 |
|
282 | 298 | // repeat lazy_star |
|
0 commit comments