• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2009 Chris Hoeppler
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 #include <boost/detail/lightweight_test.hpp>
8 
9 #include <boost/spirit/include/qi_action.hpp>
10 #include <boost/spirit/include/qi_auxiliary.hpp>
11 #include <boost/spirit/include/qi_char.hpp>
12 #include <boost/spirit/include/qi_directive.hpp>
13 #include <boost/spirit/include/qi_nonterminal.hpp>
14 #include <boost/spirit/include/qi_numeric.hpp>
15 #include <boost/spirit/include/qi_operator.hpp>
16 #include <boost/spirit/include/qi_string.hpp>
17 #include <boost/spirit/include/phoenix_bind.hpp>
18 #include <boost/spirit/include/phoenix_core.hpp>
19 #include <boost/spirit/include/phoenix_object.hpp>
20 #include <boost/spirit/include/phoenix_operator.hpp>
21 
22 #include <boost/spirit/repository/include/qi_confix.hpp>
23 
24 #include <string>
25 #include "test.hpp"
26 
27 namespace comment {
28     namespace spirit = boost::spirit;
29     namespace repo = boost::spirit::repository;
30 
31     // Define a metafunction allowing to compute the type
32     // of the confix() construct
33     template <typename Prefix, typename Suffix = Prefix>
34     struct confix_spec_traits
35     {
36         typedef typename spirit::result_of::terminal<
37             repo::tag::confix(Prefix, Suffix)
38         >::type type;
39     };
40 
41     template <typename Prefix, typename Suffix>
42     inline typename confix_spec_traits<Prefix, Suffix>::type
confix_spec(Prefix const & prefix,Suffix const & suffix)43     confix_spec(Prefix const& prefix, Suffix const& suffix)
44     {
45         return repo::confix(prefix, suffix);
46     }
47 
48     inline confix_spec_traits<std::string>::type
confix_spec(const char * prefix,const char * suffix)49     confix_spec(const char* prefix, const char* suffix)
50     {
51         return repo::confix(std::string(prefix), std::string(suffix));
52     }
53     confix_spec_traits<std::string>::type const c_comment = confix_spec("/*", "*/");
54     confix_spec_traits<std::string>::type const cpp_comment = confix_spec("//", "\n");
55 }
56 
main()57 int main()
58 {
59     using spirit_test::test_attr;
60     using spirit_test::test;
61 
62     using namespace boost::spirit::ascii;
63     using namespace boost::spirit::qi::labels;
64     using boost::spirit::qi::locals;
65     using boost::spirit::qi::rule;
66     using boost::spirit::qi::debug;
67 
68     namespace phx = boost::phoenix;
69     namespace repo = boost::spirit::repository;
70 
71     { // basic tests
72 
73         rule<char const*> start;
74 
75         start = repo::confix('a', 'c')['b'];
76         BOOST_TEST(test("abc", start));
77 
78         start = repo::confix('a', 'c')['b'] | "abd";
79         BOOST_TEST(test("abd", start));
80 
81         start = repo::confix("/*", "*/")[*(alpha - "*/")];
82         BOOST_TEST(test("/*aaaabababaaabbb*/", start));
83 
84         start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"];
85         BOOST_TEST(test("/*aaaabababaaabba*/", start));
86 
87         start = comment::c_comment[*(alpha - "*/")];
88         BOOST_TEST(test("/*aaaabababaaabbb*/", start));
89 
90         // ignore the skipper!
91         BOOST_TEST(!test("/* aaaabababaaabba*/", start, space));
92     }
93 
94     { // basic tests w/ skipper
95 
96         rule<char const*, space_type> start;
97 
98         start = repo::confix('a', 'c')['b'];
99         BOOST_TEST(test(" a b c ", start, space));
100 
101         start = repo::confix(char_('/') >> '*', '*' >> char_('/'))[*alpha - "*/"];
102         BOOST_TEST(test(" / *a       b a b a b a a a b b b * / ", start, space));
103     }
104 
105     { // context tests
106         char ch;
107         rule<char const*, char()> a;
108         a = repo::confix("/*", "*/")[alpha][_val = _1];
109 
110         BOOST_TEST(test("/*x*/", a[phx::ref(ch) = _1]));
111         BOOST_TEST(ch == 'x');
112 
113         a %= repo::confix("/*", "*/")[alpha];
114         BOOST_TEST(test_attr("/*z*/", a, ch)); // attribute is given.
115         BOOST_TEST(ch == 'z');
116     }
117 
118     { // rules test
119         rule<char const*> a, b, c, start;
120 
121         a = 'a';
122         b = 'b';
123         c = 'c';
124 
125         a.name("a");
126         b.name("b");
127         c.name("c");
128         start.name("start");
129 
130         debug(a);
131         debug(b);
132         debug(c);
133         debug(start);
134 
135         start = repo::confix(a.alias(), c.alias())[b];
136         BOOST_TEST(test("abc", start));
137     }
138 
139     { // modifiers test
140         rule<char const*> start;
141         start = no_case[repo::confix("_A_", "_Z_")["heLLo"]];
142         BOOST_TEST(test("_a_hello_z_", start));
143     }
144 
145     return boost::report_errors();
146 }
147 
148