123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*=============================================================================
- Copyright (c) 2001-2015 Joel de Guzman
- 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 <boost/detail/lightweight_test.hpp>
- #include <boost/spirit/home/x3.hpp>
- #include <boost/fusion/include/std_pair.hpp>
- #include <boost/fusion/include/vector.hpp>
- #include <vector>
- #include <string>
- #include <cstring>
- #include <iostream>
- #include "test.hpp"
- struct my_error_handler
- {
- template <typename Iterator, typename Exception, typename Context>
- boost::spirit::x3::error_handler_result
- operator()(Iterator&, Iterator const& last, Exception const& x, Context const&) const
- {
- std::cout
- << "Error! Expecting: "
- << x.which()
- << ", got: \""
- << std::string(x.where(), last)
- << "\""
- << std::endl;
- return boost::spirit::x3::error_handler_result::fail;
- }
- };
- struct my_attribute
- {
- bool alive = true;
- void access() const
- {
- BOOST_TEST(alive);
- }
- ~my_attribute()
- {
- alive = false;
- }
- friend std::ostream & operator << (std::ostream & os, my_attribute const & attr)
- {
- attr.access();
- return os << "my_attribute";
- }
- };
- int
- main()
- {
- using spirit_test::test_attr;
- using spirit_test::test;
- 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
- auto a = rule<class a>("a") = 'a';
- auto b = rule<class b>("b") = 'b';
- auto c = rule<class c>("c") = 'c';
- {
- auto start = *(a | b | c);
- BOOST_TEST(test("abcabcacb", start));
- }
- {
- rule<class start> start("start");
- auto start_def =
- start = (a | b) >> (start | b);
- BOOST_TEST(test("aaaabababaaabbb", start_def));
- BOOST_TEST(test("aaaabababaaabba", start_def, false));
- }
- }
- { // basic tests w/ skipper
- auto a = rule<class a>("a") = 'a';
- auto b = rule<class b>("b") = 'b';
- auto c = rule<class c>("c") = 'c';
- {
- auto start = *(a | b | c);
- BOOST_TEST(test(" a b c a b c a c b ", start, space));
- }
- {
- rule<class start> start("start");
- auto start_def =
- start = (a | b) >> (start | b);
- BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start_def, space));
- BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start_def, space, false));
- }
- }
- { // std::container attributes
- typedef boost::fusion::vector<int, char> fs;
- rule<class start, std::vector<fs>> start("start");
- auto start_def =
- start = *(int_ >> alpha);
- BOOST_TEST(test("1 a 2 b 3 c", start_def, space));
- }
- { // error handling
- auto r_def = '(' > int_ > ',' > int_ > ')';
- auto r = r_def.on_error(my_error_handler());
- BOOST_TEST(test("(123,456)", r));
- BOOST_TEST(!test("(abc,def)", r));
- BOOST_TEST(!test("(123,456]", r));
- BOOST_TEST(!test("(123;456)", r));
- BOOST_TEST(!test("[123,456]", r));
- }
- {
- symbols<my_attribute> a{{{ "a", my_attribute{} }}};
- auto b = rule<struct b, my_attribute>("b") = a;
- my_attribute attr;
- BOOST_TEST(test_attr("a", b, attr));
- }
- return boost::report_errors();
- }
|