• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2001-2010 Hartmut Kaiser
2 //  Copyright (c) 2001-2010 Joel de Guzman
3 //  Copyright (c) 2003 Vaclav Vesely
4 //
5 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
6 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #include <boost/mpl/print.hpp>
9 #include <boost/config/warning_disable.hpp>
10 #include <boost/detail/lightweight_test.hpp>
11 #include <boost/spirit/include/qi_char.hpp>
12 #include <boost/spirit/include/qi_string.hpp>
13 #include <boost/spirit/include/qi_nonterminal.hpp>
14 #include <boost/spirit/include/qi_numeric.hpp>
15 #include <boost/spirit/include/qi_action.hpp>
16 #include <boost/spirit/include/qi_operator.hpp>
17 
18 #include <boost/spirit/repository/include/qi_distinct.hpp>
19 
20 #include <iostream>
21 #include "test.hpp"
22 
23 using namespace boost;
24 
25 ///////////////////////////////////////////////////////////////////////////////
26 namespace distinct
27 {
28     //[qi_distinct_encapsulation
29     namespace spirit = boost::spirit;
30     namespace ascii = boost::spirit::ascii;
31     namespace repo = boost::spirit::repository;
32 
33     // Define metafunctions allowing to compute the type of the distinct()
34     // and ascii::char_() constructs
35     namespace traits
36     {
37         // Metafunction allowing to get the type of any repository::distinct(...)
38         // construct
39         template <typename Tail>
40         struct distinct_spec
41           : spirit::result_of::terminal<repo::tag::distinct(Tail)>
42         {};
43 
44         // Metafunction allowing to get the type of any ascii::char_(...) construct
45         template <typename String>
46         struct char_spec
47           : spirit::result_of::terminal<spirit::tag::ascii::char_(String)>
48         {};
49     }
50 
51     // Define a helper function allowing to create a distinct() construct from
52     // an arbitrary tail parser
53     template <typename Tail>
54     inline typename traits::distinct_spec<Tail>::type
distinct_spec(Tail const & tail)55     distinct_spec(Tail const& tail)
56     {
57         return repo::distinct(tail);
58     }
59 
60     // Define a helper function allowing to create a ascii::char_() construct
61     // from an arbitrary string representation
62     template <typename String>
63     inline typename traits::char_spec<String>::type
char_spec(String const & str)64     char_spec(String const& str)
65     {
66         return ascii::char_(str);
67     }
68 
69     // the following constructs the type of a distinct_spec holding a
70     // charset("0-9a-zA-Z_") as its tail parser
71     typedef traits::char_spec<std::string>::type charset_tag_type;
72     typedef traits::distinct_spec<charset_tag_type>::type keyword_tag_type;
73 
74     // Define a new Qi 'keyword' directive usable as a shortcut for a
75     // repository::distinct(char_(std::string("0-9a-zA-Z_")))
76     std::string const keyword_spec("0-9a-zA-Z_");
77     keyword_tag_type const keyword = distinct_spec(char_spec(keyword_spec));
78     //]
79 }
80 
81 ///////////////////////////////////////////////////////////////////////////////
main()82 int main()
83 {
84     using namespace spirit_test;
85     using namespace boost::spirit;
86 
87     {
88         using namespace boost::spirit::ascii;
89 
90         qi::rule<char const*, space_type> r;
91         r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"];
92 
93         BOOST_TEST(test("description ident", r, space));
94         BOOST_TEST(test("description:ident", r, space));
95         BOOST_TEST(test("description: ident", r, space));
96         BOOST_TEST(!test("descriptionident", r, space));
97     }
98 
99     return boost::report_errors();
100 }
101 
102