1/*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6=============================================================================*/
7#define BOOST_SPIRIT_X3_DEBUG
8
9#include <boost/spirit/home/x3.hpp>
10#include <boost/fusion/include/std_pair.hpp>
11#include <boost/fusion/include/vector.hpp>
12
13#include <vector>
14#include <string>
15#include <cstring>
16#include <iostream>
17#include "test.hpp"
18
19struct my_error_handler
20{
21 template <typename Iterator, typename Exception, typename Context>
22 boost::spirit::x3::error_handler_result
23 operator()(Iterator&, Iterator const& last, Exception const& x, Context const&) const
24 {
25 std::cout
26 << "Error! Expecting: "
27 << x.which()
28 << ", got: \""
29 << std::string(x.where(), last)
30 << "\""
31 << std::endl;
32 return boost::spirit::x3::error_handler_result::fail;
33 }
34};
35
36struct my_attribute
37{
38 bool alive = true;
39
40 void access() const
41 {
42 BOOST_TEST(alive);
43 }
44 ~my_attribute()
45 {
46 alive = false;
47 }
48
49 friend std::ostream & operator << (std::ostream & os, my_attribute const & attr)
50 {
51 attr.access();
52 return os << "my_attribute";
53 }
54};
55
56int
57main()
58{
59 using spirit_test::test_attr;
60 using spirit_test::test;
61
62 using namespace boost::spirit::x3::ascii;
63 using boost::spirit::x3::rule;
64 using boost::spirit::x3::symbols;
65 using boost::spirit::x3::int_;
66 using boost::spirit::x3::alpha;
67
68 { // basic tests
69
70 auto a = rule<class a_id>("a") = 'a';
71 auto b = rule<class b_id>("b") = 'b';
72 auto c = rule<class c_id>("c") = 'c';
73
74 {
75 auto start = *(a | b | c);
76 BOOST_TEST(test("abcabcacb", start));
77 }
78
79 {
80 rule<class start> start("start");
81 auto start_def =
82 start = (a | b) >> (start | b);
83
84 BOOST_TEST(test("aaaabababaaabbb", start_def));
85 BOOST_TEST(test("aaaabababaaabba", start_def, false));
86 }
87 }
88
89 { // basic tests w/ skipper
90
91 auto a = rule<class a_id>("a") = 'a';
92 auto b = rule<class b_id>("b") = 'b';
93 auto c = rule<class c_id>("c") = 'c';
94
95 {
96 auto start = *(a | b | c);
97 BOOST_TEST(test(" a b c a b c a c b ", start, space));
98 }
99
100 {
101 rule<class start> start("start");
102 auto start_def =
103 start = (a | b) >> (start | b);
104
105 BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start_def, space));
106 BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start_def, space, false));
107 }
108 }
109
110 { // std::container attributes
111
112 typedef boost::fusion::vector<int, char> fs;
113 rule<class start, std::vector<fs>> start("start");
114 auto start_def =
115 start = *(int_ >> alpha);
116
117 BOOST_TEST(test("1 a 2 b 3 c", start_def, space));
118 }
119
120 { // error handling
121
122 auto r_def = '(' > int_ > ',' > int_ > ')';
123 auto r = r_def.on_error(f: my_error_handler());
124
125 BOOST_TEST(test("(123,456)", r));
126 BOOST_TEST(!test("(abc,def)", r));
127 BOOST_TEST(!test("(123,456]", r));
128 BOOST_TEST(!test("(123;456)", r));
129 BOOST_TEST(!test("[123,456]", r));
130 }
131
132 {
133 symbols<my_attribute> a{{{ "a", my_attribute{} }}};
134
135 auto b = rule<struct b_id, my_attribute>("b") = a;
136
137 my_attribute attr;
138
139 BOOST_TEST(test_attr("a", b, attr));
140 }
141
142 return boost::report_errors();
143}
144

source code of boost/libs/spirit/test/x3/debug.cpp