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 
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/spirit/home/x3.hpp>
10 
11 #include <string>
12 #include <cstring>
13 #include <iostream>
14 #include "test.hpp"
15 
16 int
main()17 main()
18 {
19     using spirit_test::test_attr;
20     using spirit_test::test;
21 
22     using namespace boost::spirit::x3::ascii;
23     using boost::spirit::x3::rule;
24     using boost::spirit::x3::lit;
25     using boost::spirit::x3::unused_type;
26     using boost::spirit::x3::_attr;
27 
28     { // context tests
29 
30         char ch;
31         auto a = rule<class a, char>() = alpha;
32 
33         // this semantic action requires the context
34         auto f = [&](auto& ctx){ ch = _attr(ctx); };
35         BOOST_TEST(test("x", a[f]));
36         BOOST_TEST(ch == 'x');
37 
38         // this semantic action requires the (unused) context
39         auto f2 = [&](auto&){ ch = 'y'; };
40         BOOST_TEST(test("x", a[f2]));
41         BOOST_TEST(ch == 'y');
42 
43         // the semantic action may optionally not have any arguments at all
44         auto f3 = [&]{ ch = 'z'; };
45         BOOST_TEST(test("x", a[f3]));
46         BOOST_TEST(ch == 'z');
47 
48         BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
49         BOOST_TEST(ch == 'z');
50     }
51 
52     { // auto rules tests
53 
54         char ch = '\0';
55         auto a = rule<class a, char>() = alpha;
56         auto f = [&](auto& ctx){ ch = _attr(ctx); };
57 
58         BOOST_TEST(test("x", a[f]));
59         BOOST_TEST(ch == 'x');
60         ch = '\0';
61         BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
62         BOOST_TEST(ch == 'z');
63 
64         ch = '\0';
65         BOOST_TEST(test("x", a[f]));
66         BOOST_TEST(ch == 'x');
67         ch = '\0';
68         BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
69         BOOST_TEST(ch == 'z');
70     }
71 
72     { // auto rules tests: allow stl containers as attributes to
73       // sequences (in cases where attributes of the elements
74       // are convertible to the value_type of the container or if
75       // the element itself is an stl container with value_type
76       // that is convertible to the value_type of the attribute).
77 
78         std::string s;
79         auto f = [&](auto& ctx){ s = _attr(ctx); };
80 
81         {
82             auto r = rule<class r, std::string>()
83                 = char_ >> *(',' >> char_)
84                 ;
85 
86             BOOST_TEST(test("a,b,c,d,e,f", r[f]));
87             BOOST_TEST(s == "abcdef");
88         }
89 
90         {
91             auto r = rule<class r, std::string>()
92                 = char_ >> *(',' >> char_);
93             s.clear();
94             BOOST_TEST(test("a,b,c,d,e,f", r[f]));
95             BOOST_TEST(s == "abcdef");
96         }
97 
98         {
99             auto r = rule<class r, std::string>()
100                 = char_ >> char_ >> char_ >> char_ >> char_ >> char_;
101             s.clear();
102             BOOST_TEST(test("abcdef", r[f]));
103             BOOST_TEST(s == "abcdef");
104         }
105     }
106 
107     return boost::report_errors();
108 }
109