2
0
mirror of https://github.com/boostorg/spirit.git synced 2026-01-19 04:42:11 +00:00

Merge pull request #836 from Xeverous/error-handler-fail

X3: rollback iterator when rule's handler returns fail
This commit is contained in:
Nana Sakisaka
2025-10-06 20:36:43 +09:00
committed by GitHub
2 changed files with 25 additions and 1 deletions

View File

@@ -236,13 +236,16 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
for (;;)
{
Iterator it = first;
#if BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
try
#endif
{
if (parse_rhs_main(
rhs, first, last, context, rcontext, attr, mpl::false_()))
rhs, it, last, context, rcontext, attr, mpl::false_()))
{
first = it;
return true;
}
}

View File

@@ -12,6 +12,7 @@
#include <string>
#include <cstring>
#include <iostream>
#include <vector>
#include "test.hpp"
namespace x3 = boost::spirit::x3;
@@ -90,6 +91,8 @@ main()
using boost::spirit::x3::rule;
using boost::spirit::x3::int_;
using boost::spirit::x3::lit;
using boost::spirit::x3::lexeme;
using boost::spirit::x3::eol;
{ // show that ra = rb and ra %= rb works as expected
rule<class a, int> ra;
@@ -144,6 +147,8 @@ main()
auto r = rule<my_rule_class, char const*>()
= '(' > int_ > ',' > int_ > ')';
got_it = 0;
BOOST_TEST(test("(123,456)", r));
BOOST_TEST(!test("(abc,def)", r));
BOOST_TEST(!test("(123,456]", r));
@@ -153,6 +158,22 @@ main()
BOOST_TEST(got_it == 1);
}
{ // regression test for #833
// rules which return error_handler_result::fail should trigger iterator rollback
auto string_literal = rule<my_rule_class, std::string>()
= lexeme['"' > *~char_("\"\n\r") > '"'];
auto r = rule<class r_id, std::vector<std::string>>()
= *string_literal > eol;
got_it = 0;
BOOST_TEST(test("\"abc\"\n", r));
BOOST_TEST_THROWS(test("\"abc\n", r), x3::expectation_failure<char const*>);
BOOST_TEST(got_it == 1);
}
{ // on_success gets pre-skipped iterator
auto r = rule<on_success_gets_preskipped_iterator, char const*>()
= lit("b");