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

Revert "Merge pull request #813 from saki7/modernize-rule-parser"

This reverts commit bae393d159, reversing
changes made to c64a9146fc.
This commit is contained in:
Nana Sakisaka
2025-09-13 08:57:05 +09:00
parent 569c52220e
commit e4d3fce09f
21 changed files with 738 additions and 982 deletions

View File

@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -59,8 +58,7 @@ x3::rule<class string_rule, std::string> const string_rule("string");
auto const pair_rule_def = string_rule > x3::lit('=') > string_rule;
auto const string_rule_def = x3::lexeme[*x3::alnum];
BOOST_SPIRIT_X3_DEFINE(pair_rule)
BOOST_SPIRIT_X3_DEFINE(string_rule)
BOOST_SPIRIT_DEFINE(pair_rule, string_rule)
template <typename Container>
void test_map_support()

View File

@@ -1,29 +1,26 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#define BOOST_SPIRIT_X3_DEBUG
#include "test.hpp"
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/vector.hpp>
#include <iterator>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include "test.hpp"
struct my_error_handler
{
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Exception, typename Context>
template <typename Iterator, typename Exception, typename Context>
boost::spirit::x3::error_handler_result
operator()(It const&, Se const& last, Exception const& x, Context const&) const
operator()(Iterator&, Iterator const& last, Exception const& x, Context const&) const
{
std::cout
<< "Error! Expecting: "
@@ -49,22 +46,24 @@ struct my_attribute
alive = false;
}
friend std::ostream& operator<<(std::ostream & os, my_attribute const & attr)
friend std::ostream & operator << (std::ostream & os, my_attribute const & attr)
{
attr.access();
return os << "my_attribute";
}
};
int main()
int
main()
{
using spirit_test::test_attr;
using spirit_test::test;
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
using boost::spirit::x3::rule;
using boost::spirit::x3::symbols;
using boost::spirit::x3::int_;
using boost::spirit::x3::alpha;
{ // basic tests

View File

@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,11 +7,8 @@
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/utility/annotate_on_success.hpp>
#include <boost/spirit/home/x3/support/utility/error_reporting.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>
#include <string>
#include <sstream>
@@ -20,11 +16,10 @@ namespace x3 = boost::spirit::x3;
struct error_handler_base
{
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Exception, typename Context>
template <typename Iterator, typename Exception, typename Context>
x3::error_handler_result on_error(
It const&, Se const&,
Exception const& x, Context const& context
) const
Iterator&, Iterator const&
, Exception const& x, Context const& context) const
{
std::string message = "Error! Expecting: " + x.which() + " here:";
auto& error_handler = x3::get<x3::error_handler_tag>(context).get();
@@ -41,39 +36,35 @@ x3::rule<test_rule_class> const test_rule;
auto const test_inner_rule_def = x3::lit("bar");
auto const test_rule_def = x3::lit("foo") > test_inner_rule > x3::lit("git");
BOOST_SPIRIT_X3_DEFINE(test_inner_rule)
BOOST_SPIRIT_X3_DEFINE(test_rule)
BOOST_SPIRIT_DEFINE(test_inner_rule, test_rule)
void test(std::string const& line_break)
{
void test(std::string const& line_break) {
std::string const input("foo" + line_break + " foo" + line_break + "git");
auto const begin = std::begin(input);
auto const end = std::end(input);
{
std::stringstream stream;
x3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};
{
std::stringstream stream;
x3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};
auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
(void)x3::phrase_parse(begin, end, parser, x3::standard::space);
auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
x3::phrase_parse(begin, end, parser, x3::space);
BOOST_TEST_EQ(stream.str(), "In line 2:\nError! Expecting: \"bar\" here:\n foo\n__^_\n");
}
{
// TODO: cleanup when error_handler is reenterable
std::stringstream stream;
x3::error_handler<std::string::const_iterator> error_handler{ begin, end, stream };
auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
(void)x3::parse(begin, end, parser);
BOOST_TEST_CSTR_EQ(stream.str().c_str(), "In line 1:\nError! Expecting: \"bar\" here:\nfoo\n___^_\n");
}
BOOST_TEST_EQ(stream.str(), "In line 2:\nError! Expecting: \"bar\" here:\n foo\n__^_\n");
}
void test_line_break_first(std::string const& line_break)
{
{ // TODO: cleanup when error_handler is reenterable
std::stringstream stream;
x3::error_handler<std::string::const_iterator> error_handler{ begin, end, stream };
auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
x3::parse(begin, end, parser);
BOOST_TEST_CSTR_EQ(stream.str().c_str(), "In line 1:\nError! Expecting: \"bar\" here:\nfoo\n___^_\n");
}
}
void test_line_break_first(std::string const& line_break) {
std::string const input(line_break + "foo foo" + line_break + "git");
auto const begin = std::begin(input);
auto const end = std::end(input);
@@ -82,13 +73,12 @@ void test_line_break_first(std::string const& line_break)
x3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};
auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
(void)x3::phrase_parse(begin, end, parser, x3::space);
x3::phrase_parse(begin, end, parser, x3::space);
BOOST_TEST_EQ(stream.str(), "In line 2:\nError! Expecting: \"bar\" here:\nfoo foo\n_____^_\n");
}
int main()
{
int main() {
test("\n");
test("\r");
test("\r\n");

View File

@@ -1,16 +1,6 @@
/*=============================================================================
Copyright (c) 2019 Joel de Guzman
Copyright (c) 2019 Nikita Kniazev
Copyright (c) 2025 Nana Sakisaka
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include "grammar.hpp"
auto const grammar_def = x3::int_;
BOOST_SPIRIT_X3_DEFINE(grammar)
BOOST_SPIRIT_X3_INSTANTIATE(grammar_type, char const*, x3::unused_type)
BOOST_SPIRIT_DEFINE(grammar)
BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type)

View File

@@ -1,17 +1,7 @@
/*=============================================================================
Copyright (c) 2019 Joel de Guzman
Copyright (c) 2019 Nikita Kniazev
Copyright (c) 2025 Nana Sakisaka
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
x3::rule<struct grammar_r, int> const grammar;
using grammar_type = decltype(grammar);
BOOST_SPIRIT_X3_DECLARE(grammar_type)
BOOST_SPIRIT_DECLARE(grammar_type)

View File

@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -21,10 +20,10 @@ rule<class indirect_rule, int> indirect_rule = "indirect_rule";
auto const direct_rule_def = boost::spirit::x3::int_;
auto const indirect_rule_def = direct_rule;
BOOST_SPIRIT_X3_DEFINE(direct_rule)
BOOST_SPIRIT_X3_DEFINE(indirect_rule)
BOOST_SPIRIT_DEFINE(direct_rule, indirect_rule)
int main()
int
main()
{
using namespace boost::spirit::x3::ascii;
using boost::spirit::x3::omit;

View File

@@ -22,8 +22,7 @@ rule<class indirect_rule, int> indirect_rule = "indirect_rule";
auto const direct_rule_def = boost::spirit::x3::int_;
auto const indirect_rule_def = direct_rule;
BOOST_SPIRIT_X3_DEFINE(direct_rule)
BOOST_SPIRIT_X3_DEFINE(indirect_rule)
BOOST_SPIRIT_DEFINE(direct_rule, indirect_rule)
int main()
{
@@ -84,7 +83,7 @@ int main()
boost::variant<int, range> attr;
std::string str("test");
(void)parse(str.begin(), str.end(), (int_ | raw[*char_]), attr);
parse(str.begin(), str.end(), (int_ | raw[*char_]), attr);
auto rng = boost::get<range>(attr);
BOOST_TEST(std::string(rng.begin(), rng.end()) == "test");
@@ -93,7 +92,7 @@ int main()
{
std::vector<boost::iterator_range<std::string::iterator>> attr;
std::string str("123abcd");
(void)parse(str.begin(), str.end()
parse(str.begin(), str.end()
, (raw[int_] >> raw[*char_])
, attr
);
@@ -105,7 +104,7 @@ int main()
{
std::pair<int, boost::iterator_range<std::string::iterator>> attr;
std::string str("123abcd");
(void)parse(str.begin(), str.end()
parse(str.begin(), str.end()
, (int_ >> raw[*char_])
, attr
);

View File

@@ -54,8 +54,7 @@ boost::spirit::x3::rule<class b_r, stationary> const b;
auto const a_def = '{' >> boost::spirit::x3::int_ >> '}';
auto const b_def = a;
BOOST_SPIRIT_X3_DEFINE(a)
BOOST_SPIRIT_X3_DEFINE(b)
BOOST_SPIRIT_DEFINE(a, b)
}
@@ -70,7 +69,7 @@ boost::spirit::x3::rule<class grammar_r, node_t> const grammar;
auto const grammar_def = '[' >> grammar % ',' >> ']' | boost::spirit::x3::int_;
BOOST_SPIRIT_X3_DEFINE(grammar)
BOOST_SPIRIT_DEFINE(grammar)
}
@@ -96,9 +95,9 @@ namespace check_recursive_tuple {
x3::rule<class grammar_r, recursive_tuple> const grammar;
auto const grammar_def = x3::int_ >> ('{' >> grammar % ',' >> '}' | x3::eps);
BOOST_SPIRIT_X3_DEFINE(grammar)
BOOST_SPIRIT_DEFINE(grammar)
BOOST_SPIRIT_X3_INSTANTIATE(decltype(grammar), char const*, x3::unused_type)
BOOST_SPIRIT_INSTANTIATE(decltype(grammar), char const*, x3::unused_type)
}

View File

@@ -13,25 +13,19 @@
#include <boost/fusion/include/at.hpp>
#include <boost/variant.hpp>
#include <iterator>
#include <string>
#include <cstring>
#include <iostream>
namespace x3 = boost::spirit::x3;
namespace {
int got_it = 0;
}
struct my_rule_class
{
//template <std::forward_iterator It, std::sentinel_for<It> Se, typename Exception, typename Context>
//x3::error_handler_result
//on_error(It const&, Se const& last, Exception const& x, Context const&)
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Exception, typename Context>
template <typename Iterator, typename Exception, typename Context>
x3::error_handler_result
on_error(It const&, Se const& last, Exception const& x, Context const&)
on_error(Iterator&, Iterator const& last, Exception const& x, Context const&)
{
std::cout
<< "Error! Expecting: "
@@ -44,9 +38,9 @@ struct my_rule_class
return x3::error_handler_result::fail;
}
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename Context>
void
on_success(It const&, Se const&, Attribute&, Context const&)
template <typename Iterator, typename Attribute, typename Context>
inline void
on_success(Iterator const&, Iterator const&, Attribute&, Context const&)
{
++got_it;
}
@@ -56,28 +50,51 @@ struct on_success_gets_preskipped_iterator
{
static bool ok;
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename Context>
void on_success(It before, Se const& after, Attribute&, Context const&)
template <typename Iterator, typename Attribute, typename Context>
void on_success(Iterator before, Iterator& after, Attribute&, Context const&)
{
bool const before_was_b = 'b' == *before;
ok = before_was_b && (++before == after);
ok = ('b' == *before) && (++before == after);
}
};
bool on_success_gets_preskipped_iterator::ok = false;
struct on_success_advance_iterator
{
template <typename Iterator, typename Attribute, typename Context>
void on_success(Iterator const&, Iterator& after, Attribute&, Context const&)
{
++after;
}
};
struct on_success_advance_iterator_mutref
{
template <typename Iterator, typename Attribute, typename Context>
void on_success(Iterator&, Iterator& after, Attribute&, Context const&)
{
++after;
}
};
struct on_success_advance_iterator_byval
{
template <typename Iterator, typename Attribute, typename Context>
void on_success(Iterator, Iterator& after, Attribute&, Context const&)
{
++after;
}
};
int main()
int
main()
{
using spirit_test::test_attr;
using spirit_test::test;
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
using boost::spirit::x3::rule;
using boost::spirit::x3::int_;
using boost::spirit::x3::lit;
// show that ra = rb and ra %= rb works as expected
{
{ // show that ra = rb and ra %= rb works as expected
rule<class a, int> ra;
rule<class b, int> rb;
int attr;
@@ -95,8 +112,7 @@ int main()
BOOST_TEST(attr == 123);
}
// show that ra %= rb works as expected with semantic actions
{
{ // show that ra %= rb works as expected with semantic actions
rule<class a, int> ra;
rule<class b, int> rb;
int attr;
@@ -112,8 +128,8 @@ int main()
}
// std::string as container attribute with auto rules
{
{ // std::string as container attribute with auto rules
std::string attr;
// test deduced auto rule behavior
@@ -126,8 +142,8 @@ int main()
BOOST_TEST(attr == "x");
}
// error handling
{
{ // error handling
auto r = rule<my_rule_class, char const*>()
= '(' > int_ > ',' > int_ > ')';
@@ -140,23 +156,34 @@ int main()
BOOST_TEST(got_it == 1);
}
// on_success gets pre-skipped iterator
{
{ // on_success gets pre-skipped iterator
auto r = rule<on_success_gets_preskipped_iterator, char const*>()
= lit("b");
BOOST_TEST(test("a b", 'a' >> r, lit(' ')));
BOOST_TEST(on_success_gets_preskipped_iterator::ok);
}
{ // on_success handler mutable 'after' iterator
auto r1 = rule<on_success_advance_iterator, char const*>()
= lit("ab");
BOOST_TEST(test("abc", r1));
auto r2 = rule<on_success_advance_iterator_mutref, char const*>()
= lit("ab");
BOOST_TEST(test("abc", r2));
auto r3 = rule<on_success_advance_iterator_byval, char const*>()
= lit("ab");
BOOST_TEST(test("abc", r3));
}
{
using v_type = boost::variant<double, int>;
typedef boost::variant<double, int> v_type;
auto r1 = rule<class r1_id, v_type>()
= int_;
v_type v;
BOOST_TEST(test_attr("1", r1, v) && v.which() == 1 &&
boost::get<int>(v) == 1);
using ov_type = boost::optional<int>;
typedef boost::optional<int> ov_type;
auto r2 = rule<class r2_id, ov_type>()
= int_;
ov_type ov;
@@ -174,19 +201,21 @@ int main()
BOOST_TEST(test_attr("1", r, v) && at_c<0>(v) == 1);
}
// attribute compatibility test
{
constexpr auto expr = int_;
{ // attribute compatibility test
using boost::spirit::x3::rule;
using boost::spirit::x3::int_;
long long i = 0;
BOOST_TEST(test_attr("1", expr, i) && i == 1);
auto const expr = int_;
constexpr rule<class int_rule, int> int_rule("int_rule");
constexpr auto int_rule_def = int_;
constexpr auto start = int_rule = int_rule_def;
long long i;
BOOST_TEST(test_attr("1", expr, i) && i == 1); // ok
long long j = 0;
BOOST_TEST(test_attr("1", start, j) && j == 1);
const rule< class int_rule, int > int_rule( "int_rule" );
auto const int_rule_def = int_;
auto const start = int_rule = int_rule_def;
long long j;
BOOST_TEST(test_attr("1", start, j) && j == 1); // error
}
return boost::report_errors();

View File

@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2019 Nikita Kniazev
Copyright (c) 2025 Nana Sakisaka
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,19 +19,19 @@ auto nop = [](auto const&){};
x3::rule<class used_attr1_r, int> used_attr1;
auto const used_attr1_def = used_attr::grammar[nop];
BOOST_SPIRIT_X3_DEFINE(used_attr1);
BOOST_SPIRIT_DEFINE(used_attr1);
x3::rule<class used_attr2_r, int> used_attr2;
auto const used_attr2_def = unused_attr::grammar[nop];
BOOST_SPIRIT_X3_DEFINE(used_attr2);
BOOST_SPIRIT_DEFINE(used_attr2);
x3::rule<class unused_attr1_r> unused_attr1;
auto const unused_attr1_def = used_attr::grammar[nop];
BOOST_SPIRIT_X3_DEFINE(unused_attr1);
BOOST_SPIRIT_DEFINE(unused_attr1);
x3::rule<class unused_attr2_r> unused_attr2;
auto const unused_attr2_def = unused_attr::grammar[nop];
BOOST_SPIRIT_X3_DEFINE(unused_attr2);
BOOST_SPIRIT_DEFINE(unused_attr2);
}

View File

@@ -14,36 +14,36 @@
namespace unused_attr {
auto const skipper_def = x3::standard::lit('*');
BOOST_SPIRIT_X3_DEFINE(skipper)
BOOST_SPIRIT_X3_INSTANTIATE(skipper_type, char const*, x3::unused_type)
BOOST_SPIRIT_DEFINE(skipper)
BOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, x3::unused_type)
auto const skipper2_def = x3::standard::lit('#');
BOOST_SPIRIT_X3_DEFINE(skipper2)
BOOST_SPIRIT_X3_INSTANTIATE(skipper2_type, char const*, x3::unused_type)
BOOST_SPIRIT_DEFINE(skipper2)
BOOST_SPIRIT_INSTANTIATE(skipper2_type, char const*, x3::unused_type)
auto const grammar_def = *x3::standard::lit('=');
BOOST_SPIRIT_X3_DEFINE(grammar)
BOOST_SPIRIT_X3_INSTANTIATE(grammar_type, char const*, x3::unused_type)
BOOST_SPIRIT_DEFINE(grammar)
BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type)
using skipper_context_type = typename x3::phrase_parse_context<skipper_type, char const*>::type;
BOOST_SPIRIT_X3_INSTANTIATE(grammar_type, char const*, skipper_context_type)
BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, skipper_context_type)
using skipper2_context_type = typename x3::phrase_parse_context<skipper2_type, char const*>::type;
BOOST_SPIRIT_X3_INSTANTIATE(grammar_type, char const*, skipper2_context_type)
BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, skipper2_context_type)
}
namespace used_attr {
auto const skipper_def = x3::standard::space;
BOOST_SPIRIT_X3_DEFINE(skipper)
BOOST_SPIRIT_X3_INSTANTIATE(skipper_type, char const*, x3::unused_type)
BOOST_SPIRIT_DEFINE(skipper)
BOOST_SPIRIT_INSTANTIATE(skipper_type, char const*, x3::unused_type)
auto const grammar_def = x3::int_;
BOOST_SPIRIT_X3_DEFINE(grammar)
BOOST_SPIRIT_X3_INSTANTIATE(grammar_type, char const*, x3::unused_type)
BOOST_SPIRIT_DEFINE(grammar)
BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, x3::unused_type)
using skipper_context_type = typename x3::phrase_parse_context<skipper_type, char const*>::type;
BOOST_SPIRIT_X3_INSTANTIATE(grammar_type, char const*, skipper_context_type)
BOOST_SPIRIT_INSTANTIATE(grammar_type, char const*, skipper_context_type)
}

View File

@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2019 Nikita Kniazev
Copyright (c) 2025 Nana Sakisaka
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,7 +8,7 @@
#include <boost/spirit/home/x3.hpp>
// Check that `BOOST_SPIRIT_X3_INSTANTIATE` instantiates `parse_rule` with proper
// Check that `BOOST_SPIRIT_INSTANTIATE` instantiates `parse_rule` with proper
// types when a rule has no attribute.
namespace unused_attr {
@@ -19,17 +18,17 @@ namespace x3 = boost::spirit::x3;
// skipper must has no attribute, checks `parse` and `skip_over`
using skipper_type = x3::rule<class skipper_r>;
const skipper_type skipper;
BOOST_SPIRIT_X3_DECLARE(skipper_type)
BOOST_SPIRIT_DECLARE(skipper_type)
// the `unused_type const` must have the same effect as no attribute
using skipper2_type = x3::rule<class skipper2_r, x3::unused_type const>;
const skipper2_type skipper2;
BOOST_SPIRIT_X3_DECLARE(skipper2_type)
BOOST_SPIRIT_DECLARE(skipper2_type)
// grammar must has no attribute, checks `parse` and `phrase_parse`
using grammar_type = x3::rule<class grammar_r>;
const grammar_type grammar;
BOOST_SPIRIT_X3_DECLARE(grammar_type)
BOOST_SPIRIT_DECLARE(grammar_type)
}
@@ -41,10 +40,10 @@ namespace x3 = boost::spirit::x3;
using skipper_type = x3::rule<class skipper_r>;
const skipper_type skipper;
BOOST_SPIRIT_X3_DECLARE(skipper_type)
BOOST_SPIRIT_DECLARE(skipper_type)
using grammar_type = x3::rule<class grammar_r, int, true>;
const grammar_type grammar;
BOOST_SPIRIT_X3_DECLARE(grammar_type)
BOOST_SPIRIT_DECLARE(grammar_type)
}

View File

@@ -1,15 +1,11 @@
/*=============================================================================
Copyright (c) 2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include "test.hpp"
#include <boost/spirit/home/x3.hpp>
#include <iterator>
#include "test.hpp"
namespace x3 = boost::spirit::x3;
@@ -17,23 +13,24 @@ struct my_tag;
struct my_rule_class
{
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Exception, typename Context>
[[nodiscard]] x3::error_handler_result
on_error(It const&, Se const&, Exception const&, Context const& context)
template <typename Iterator, typename Exception, typename Context>
x3::error_handler_result
on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
{
++x3::get<my_tag>(context);
x3::get<my_tag>(context)++;
return x3::error_handler_result::fail;
}
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename Context>
void
on_success(It const&, Se const&, Attribute&, Context const& context)
template <typename Iterator, typename Attribute, typename Context>
inline void
on_success(Iterator const&, Iterator const&, Attribute&, Context const& context)
{
++x3::get<my_tag>(context);
x3::get<my_tag>(context)++;
}
};
int main()
int
main()
{
using spirit_test::test_attr;
using spirit_test::test;