@@ -785,8 +785,7 @@ class encoder
785
785
786
786
void dpsh (directives enable, directives disable)
787
787
{
788
- directives const ancestor_mode = mode_.back ();
789
- mode_.push_back ((ancestor_mode & ~disable) | enable);
788
+ mode_.push_back ((mode_.back () & ~disable) | enable);
790
789
}
791
790
792
791
void dpop (directives relay)
@@ -1409,17 +1408,16 @@ template <std::size_t NMin, std::size_t NMax, class E>
1409
1408
if (d.should_skip ())
1410
1409
return false ;
1411
1410
d.commit_eps ();
1412
- if constexpr (std::is_same_v<std::decay_t <E>, match_any_expression>) {
1411
+ if constexpr (std::is_same_v<std::decay_t <E>, match_any_expression>)
1413
1412
d.encode_min_max (opcode::repeat_any, NMin, NMax);
1414
- } else if constexpr (std::is_same_v<std::decay_t <E>, ctype_expression<unicode::ctype::blank>>) {
1413
+ else if constexpr (std::is_same_v<std::decay_t <E>, ctype_expression<unicode::ctype::blank>>)
1415
1414
d.encode_min_max (opcode::repeat_blank, NMin, NMax);
1416
- } else if constexpr (std::is_same_v<std::decay_t <E>, ctype_expression<unicode::ctype::space>>) {
1415
+ else if constexpr (std::is_same_v<std::decay_t <E>, ctype_expression<unicode::ctype::space>>)
1417
1416
d.encode_min_max (opcode::repeat_space, NMin, NMax);
1418
- } else if constexpr (std::is_same_v<std::decay_t <E>, char_expression>) {
1417
+ else if constexpr (std::is_same_v<std::decay_t <E>, char_expression>)
1419
1418
d.encode_char_or_set (opcode::repeat_octet, opcode::repeat_set, e.c , NMin, NMax);
1420
- } else if constexpr (std::is_same_v<std::decay_t <E>, char32_range_expression>) {
1419
+ else if constexpr (std::is_same_v<std::decay_t <E>, char32_range_expression>)
1421
1420
d.encode_min_max (opcode::repeat_set, NMin, NMax, e.make_rune_set (d.mode ()));
1422
- }
1423
1421
return true ;
1424
1422
} else if constexpr (std::is_same_v<std::decay_t <E>, string_expression>) {
1425
1423
if (d.should_skip () || (e.text .size () != 1 ))
@@ -1444,9 +1442,10 @@ struct repetition_expression : unary_encoder_expression_interface<repetition_exp
1444
1442
if constexpr (is_repetition_expression_optimizable_v<std::decay_t <E1 >>)
1445
1443
if (repetition_encode_optimized<NMin, NMax>(this ->e1 , d))
1446
1444
return m;
1445
+ d.skip (directives::none, directives::lexeme | directives::noskip);
1447
1446
auto const start = d.encode (opcode::jump);
1448
1447
auto const loop_body = d.here ();
1449
- d.dpsh (directives::postskip, directives::none );
1448
+ d.dpsh (directives::postskip, directives::preskip );
1450
1449
auto m2 = this ->e1 .evaluate (d, m);
1451
1450
d.dpop (NMin > 0 ? directives::eps : directives::none);
1452
1451
d.encode (opcode::ret);
@@ -1467,7 +1466,7 @@ struct repetition_expression : unary_encoder_expression_interface<repetition_exp
1467
1466
template <class E1 , std::size_t NCount>
1468
1467
struct repetition_expression <E1 , NCount, NCount> : unary_encoder_expression_interface<repetition_expression<E1 , NCount, NCount>, E1 >
1469
1468
{
1470
- static_assert ((NCount > 0 ) && (NCount <= max_repetitions));
1469
+ static_assert ((NCount > 1 ) && (NCount <= max_repetitions));
1471
1470
using base_type = unary_encoder_expression_interface<repetition_expression<E1 , NCount, NCount>, E1 >;
1472
1471
constexpr explicit repetition_expression (E1 const & e) : base_type{e} {}
1473
1472
@@ -1477,9 +1476,10 @@ struct repetition_expression<E1, NCount, NCount> : unary_encoder_expression_inte
1477
1476
if constexpr (is_repetition_expression_optimizable_v<std::decay_t <E1 >>)
1478
1477
if (repetition_encode_optimized<NCount, NCount>(this ->e1 , d))
1479
1478
return m;
1479
+ d.skip (directives::none, directives::lexeme | directives::noskip);
1480
1480
auto const start = d.encode (opcode::jump);
1481
1481
auto const loop_body = d.here ();
1482
- d.dpsh (directives::postskip, directives::none );
1482
+ d.dpsh (directives::postskip, directives::preskip );
1483
1483
auto m2 = this ->e1 .evaluate (d, m);
1484
1484
d.dpop (directives::eps);
1485
1485
d.encode (opcode::ret);
@@ -1493,7 +1493,7 @@ struct repetition_expression<E1, NCount, NCount> : unary_encoder_expression_inte
1493
1493
template <class E1 , std::size_t NMin>
1494
1494
struct repetition_expression <E1 , NMin, forever> : unary_encoder_expression_interface<repetition_expression<E1 , NMin, forever>, E1 >
1495
1495
{
1496
- static_assert ((NMin > 0 ) && (NMin <= max_repetitions));
1496
+ static_assert ((NMin > 1 ) && (NMin <= max_repetitions));
1497
1497
using base_type = unary_encoder_expression_interface<repetition_expression<E1 , NMin, forever>, E1 >;
1498
1498
constexpr explicit repetition_expression (E1 const & e) : base_type{e} {}
1499
1499
@@ -1503,9 +1503,10 @@ struct repetition_expression<E1, NMin, forever> : unary_encoder_expression_inter
1503
1503
if constexpr (is_repetition_expression_optimizable_v<std::decay_t <E1 >>)
1504
1504
if (repetition_encode_optimized<NMin, forever>(this ->e1 , d))
1505
1505
return m;
1506
+ d.skip (directives::none, directives::lexeme | directives::noskip);
1506
1507
auto const start = d.encode (opcode::jump);
1507
1508
auto const loop_body = d.here ();
1508
- d.dpsh (directives::postskip, directives::none );
1509
+ d.dpsh (directives::postskip, directives::preskip );
1509
1510
auto m2 = this ->e1 .evaluate (d, m);
1510
1511
d.dpop (NMin > 0 ? directives::eps : directives::none);
1511
1512
d.encode (opcode::ret);
@@ -1535,9 +1536,10 @@ struct repetition_expression<E1, 0, NMax> : unary_encoder_expression_interface<r
1535
1536
if constexpr (is_repetition_expression_optimizable_v<std::decay_t <E1 >>)
1536
1537
if (repetition_encode_optimized<0 , NMax>(this ->e1 , d))
1537
1538
return m;
1539
+ d.skip (directives::none, directives::lexeme | directives::noskip);
1538
1540
auto const start = d.encode (opcode::jump);
1539
1541
auto const loop_body = d.here ();
1540
- d.dpsh (directives::postskip, directives::none );
1542
+ d.dpsh (directives::postskip, directives::preskip );
1541
1543
auto m2 = this ->e1 .evaluate (d, m);
1542
1544
d.dpop (directives::none);
1543
1545
d.encode (opcode::ret);
@@ -1596,9 +1598,10 @@ struct repetition_expression<E1, 0, forever> : unary_encoder_expression_interfac
1596
1598
if constexpr (is_repetition_expression_optimizable_v<std::decay_t <E1 >>)
1597
1599
if (repetition_encode_optimized<0 , forever>(this ->e1 , d))
1598
1600
return m;
1601
+ d.skip (directives::none, directives::lexeme | directives::noskip);
1599
1602
auto const choice = d.encode (opcode::choice);
1600
1603
auto const expression = d.here ();
1601
- d.dpsh (directives::postskip, directives::none );
1604
+ d.dpsh (directives::postskip, directives::preskip );
1602
1605
auto m2 = this ->e1 .evaluate (d, m);
1603
1606
d.dpop (directives::none);
1604
1607
auto const commit = d.encode (opcode::commit_partial);
@@ -1629,15 +1632,13 @@ struct repetition_expression<E1, 1, 2> : unary_encoder_expression_interface<repe
1629
1632
if (repetition_encode_optimized<1 , 2 >(this ->e1 , d))
1630
1633
return m;
1631
1634
(void )this ->e1 .evaluate (d, m);
1632
- d.dpsh (directives::preskip, directives::postskip);
1633
1635
auto const choice = d.encode (opcode::choice);
1634
- d.dpsh (directives::none , directives::none );
1636
+ d.dpsh (directives::preskip , directives::postskip );
1635
1637
auto m2 = this ->e1 .evaluate (d, m);
1636
1638
d.dpop (directives::eps);
1637
1639
auto const commit = d.encode (opcode::commit);
1638
1640
d.jump_to_here (choice);
1639
1641
d.jump_to_here (commit);
1640
- d.dpop (directives::eps);
1641
1642
return m2;
1642
1643
}
1643
1644
};
@@ -1655,16 +1656,15 @@ struct repetition_expression<E1, 1, forever> : unary_encoder_expression_interfac
1655
1656
if (repetition_encode_optimized<1 , forever>(this ->e1 , d))
1656
1657
return m;
1657
1658
(void )this ->e1 .evaluate (d, m);
1658
- d.dpsh (directives::preskip , directives::postskip );
1659
+ d.skip (directives::none , directives::lexeme | directives::noskip );
1659
1660
auto const choice = d.encode (opcode::choice);
1660
1661
auto const expression = d.here ();
1661
- d.dpsh (directives::postskip, directives::none );
1662
+ d.dpsh (directives::postskip, directives::preskip );
1662
1663
auto m2 = this ->e1 .evaluate (d, m);
1663
1664
d.dpop (directives::none);
1664
1665
auto const commit = d.encode (opcode::commit_partial);
1665
1666
d.jump_to_here (choice);
1666
1667
d.jump_to_target (commit, expression);
1667
- d.dpop (directives::eps);
1668
1668
return m2;
1669
1669
}
1670
1670
};
@@ -2076,11 +2076,27 @@ inline namespace operators {
2076
2076
[[nodiscard]] inline auto operator " " _srx(char const * s, std::size_t n) { return cased[basic_regular_expression{std::string_view{s, n}}]; }
2077
2077
[[nodiscard]] constexpr auto operator " " _fail(char const * s, std::size_t n) { return failure{std::string_view{s, n}}; }
2078
2078
2079
+ template <class E1 , class E2 , class = std::enable_if_t <is_expression_v<E1 > && is_expression_v<E2 >>>
2080
+ [[nodiscard]] constexpr auto operator |(E1 const & e1 , E2 const & e2 )
2081
+ {
2082
+ if constexpr (detail::is_template_instantiation_of_v<E1 , choice_expression>)
2083
+ return choice_expression{e1 .e1 , e1 .e2 | e2 };
2084
+ else
2085
+ return choice_expression{make_expression (e1 ), make_expression (e2 )};
2086
+ }
2087
+
2088
+ template <class E1 , class E2 , class = std::enable_if_t <is_expression_v<E1 > && is_expression_v<E2 >>>
2089
+ [[nodiscard]] constexpr auto operator >(E1 const & e1 , E2 const & e2 )
2090
+ {
2091
+ if constexpr (detail::is_template_instantiation_of_v<E1 , sequence_expression>)
2092
+ return sequence_expression{e1 .e1 , e1 .e2 > e2 };
2093
+ else
2094
+ return sequence_expression{make_expression (e1 ), make_expression (e2 )};
2095
+ }
2096
+
2079
2097
template <class E , class = std::enable_if_t <is_expression_v<E>>> [[nodiscard]] constexpr auto operator !(E const & e) { return negative_lookahead_expression{make_expression (e)}; }
2080
2098
template <class E , class = std::enable_if_t <is_expression_v<E>>> [[nodiscard]] constexpr auto operator &(E const & e) { return positive_lookahead_expression{make_expression (e)}; } // NOLINT(google-runtime-operator)
2081
2099
template <class E , class = std::enable_if_t <is_expression_v<E>>> [[nodiscard]] constexpr auto operator *(E const & e) { return repetition_expression<std::decay_t <decltype (make_expression (e))>, 0 , forever>{make_expression (e)}; }
2082
- template <class E1 , class E2 , class = std::enable_if_t <is_expression_v<E1 > && is_expression_v<E2 >>> [[nodiscard]] constexpr auto operator |(E1 const & e1 , E2 const & e2 ) { return choice_expression{make_expression (e1 ), make_expression (e2 )}; }
2083
- template <class E1 , class E2 , class = std::enable_if_t <is_expression_v<E1 > && is_expression_v<E2 >>> [[nodiscard]] constexpr auto operator >(E1 const & e1 , E2 const & e2 ) { return sequence_expression{make_expression (e1 ), make_expression (e2 )}; }
2084
2100
template <class E1 , class E2 , class = std::enable_if_t <is_expression_v<E1 > && is_expression_v<E2 >>> [[nodiscard]] constexpr auto operator >>(E1 const & e1 , E2 const & e2 ) { return e1 > *(e2 > e1 ); }
2085
2101
template <class T , class E , class = std::enable_if_t <is_expression_v<E>>> [[nodiscard]] constexpr auto operator %(T& target, E const & e) { return assign_to_expression{make_expression (e), std::addressof (target)}; }
2086
2102
template <class E , class = std::enable_if_t <is_expression_v<E>>> [[nodiscard]] constexpr auto operator ^(E const & e, error_response r) { return e > recover_response_expression{r}; }
@@ -3384,8 +3400,8 @@ class basic_parser : public parser_base
3384
3400
if (!fail (fail_count))
3385
3401
return false ;
3386
3402
accept_or_drain_if_deferred ();
3387
- fail_count = 0 ;
3388
3403
}
3404
+ fail_count = 0 ;
3389
3405
}
3390
3406
}
3391
3407
if (!success_)
0 commit comments