1 /*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
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 =============================================================================*/
8 #include <boost/spirit/home/x3.hpp>
15 namespace x3
= boost::spirit::x3
;
17 struct check_no_rule_injection_parser
18 : x3::parser
<check_no_rule_injection_parser
>
20 typedef x3::unused_type attribute_type
;
21 static bool const has_attribute
= false;
23 template <typename Iterator
, typename Context
24 , typename RuleContext
, typename Attribute
>
25 bool parse(Iterator
&, Iterator
const&, Context
const&,
26 RuleContext
&, Attribute
&) const
28 static_assert(std::is_same
<Context
, x3::unused_type
>::value
,
29 "no rule definition injection should occur");
32 } const check_no_rule_injection
{};
37 using spirit_test::test_attr
;
38 using spirit_test::test
;
40 using namespace boost::spirit::x3::ascii
;
41 using boost::spirit::x3::rule
;
42 using boost::spirit::x3::lit
;
43 using boost::spirit::x3::unused_type
;
44 using boost::spirit::x3::_attr
;
49 auto a
= rule
<class a_id
, char>() = alpha
;
51 // this semantic action requires the context
52 auto f
= [&](auto& ctx
){ ch
= _attr(ctx
); };
53 BOOST_TEST(test("x", a
[f
]));
54 BOOST_TEST(ch
== 'x');
56 // this semantic action requires the (unused) context
57 auto f2
= [&](auto&){ ch
= 'y'; };
58 BOOST_TEST(test("x", a
[f2
]));
59 BOOST_TEST(ch
== 'y');
61 // the semantic action may optionally not have any arguments at all
62 auto f3
= [&]{ ch
= 'z'; };
63 BOOST_TEST(test("x", a
[f3
]));
64 BOOST_TEST(ch
== 'z');
66 BOOST_TEST(test_attr("z", a
, ch
)); // attribute is given.
67 BOOST_TEST(ch
== 'z');
73 auto a
= rule
<class a_id
, char>() = alpha
;
74 auto f
= [&](auto& ctx
){ ch
= _attr(ctx
); };
76 BOOST_TEST(test("x", a
[f
]));
77 BOOST_TEST(ch
== 'x');
79 BOOST_TEST(test_attr("z", a
, ch
)); // attribute is given.
80 BOOST_TEST(ch
== 'z');
83 BOOST_TEST(test("x", a
[f
]));
84 BOOST_TEST(ch
== 'x');
86 BOOST_TEST(test_attr("z", a
, ch
)); // attribute is given.
87 BOOST_TEST(ch
== 'z');
90 { // auto rules tests: allow stl containers as attributes to
91 // sequences (in cases where attributes of the elements
92 // are convertible to the value_type of the container or if
93 // the element itself is an stl container with value_type
94 // that is convertible to the value_type of the attribute).
97 auto f
= [&](auto& ctx
){ s
= _attr(ctx
); };
100 auto r
= rule
<class r_id
, std::string
>()
101 = char_
>> *(',' >> char_
)
104 BOOST_TEST(test("a,b,c,d,e,f", r
[f
]));
105 BOOST_TEST(s
== "abcdef");
109 auto r
= rule
<class r_id
, std::string
>()
110 = char_
>> *(',' >> char_
);
112 BOOST_TEST(test("a,b,c,d,e,f", r
[f
]));
113 BOOST_TEST(s
== "abcdef");
117 auto r
= rule
<class r_id
, std::string
>()
118 = char_
>> char_
>> char_
>> char_
>> char_
>> char_
;
120 BOOST_TEST(test("abcdef", r
[f
]));
121 BOOST_TEST(s
== "abcdef");
126 BOOST_TEST(test("", rule
<class a
>{} = check_no_rule_injection
));
127 BOOST_TEST(test("", rule
<class a
>{} %= check_no_rule_injection
));
130 return boost::report_errors();