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