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 commitbae393d159, reversing changes made toc64a9146fc.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user