102 lines
3.3 KiB
C++
102 lines
3.3 KiB
C++
// Copyright (c) 2001-2010 Hartmut Kaiser
|
|
// Copyright (c) 2001-2010 Joel de Guzman
|
|
// Copyright (c) 2003 Vaclav Vesely
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
#include <boost/mpl/print.hpp>
|
|
#include <boost/config/warning_disable.hpp>
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
#include <boost/spirit/include/qi_char.hpp>
|
|
#include <boost/spirit/include/qi_string.hpp>
|
|
#include <boost/spirit/include/qi_nonterminal.hpp>
|
|
#include <boost/spirit/include/qi_numeric.hpp>
|
|
#include <boost/spirit/include/qi_action.hpp>
|
|
#include <boost/spirit/include/qi_operator.hpp>
|
|
|
|
#include <boost/spirit/repository/include/qi_distinct.hpp>
|
|
|
|
#include <iostream>
|
|
#include "test.hpp"
|
|
|
|
using namespace boost;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace distinct
|
|
{
|
|
//[qi_distinct_encapsulation
|
|
namespace spirit = boost::spirit;
|
|
namespace ascii = boost::spirit::ascii;
|
|
namespace repo = boost::spirit::repository;
|
|
|
|
// Define metafunctions allowing to compute the type of the distinct()
|
|
// and ascii::char_() constructs
|
|
namespace traits
|
|
{
|
|
// Metafunction allowing to get the type of any repository::distinct(...)
|
|
// construct
|
|
template <typename Tail>
|
|
struct distinct_spec
|
|
: spirit::result_of::terminal<repo::tag::distinct(Tail)>
|
|
{};
|
|
|
|
// Metafunction allowing to get the type of any ascii::char_(...) construct
|
|
template <typename String>
|
|
struct char_spec
|
|
: spirit::result_of::terminal<spirit::tag::ascii::char_(String)>
|
|
{};
|
|
}
|
|
|
|
// Define a helper function allowing to create a distinct() construct from
|
|
// an arbitrary tail parser
|
|
template <typename Tail>
|
|
inline typename traits::distinct_spec<Tail>::type
|
|
distinct_spec(Tail const& tail)
|
|
{
|
|
return repo::distinct(tail);
|
|
}
|
|
|
|
// Define a helper function allowing to create a ascii::char_() construct
|
|
// from an arbitrary string representation
|
|
template <typename String>
|
|
inline typename traits::char_spec<String>::type
|
|
char_spec(String const& str)
|
|
{
|
|
return ascii::char_(str);
|
|
}
|
|
|
|
// the following constructs the type of a distinct_spec holding a
|
|
// charset("0-9a-zA-Z_") as its tail parser
|
|
typedef traits::char_spec<std::string>::type charset_tag_type;
|
|
typedef traits::distinct_spec<charset_tag_type>::type keyword_tag_type;
|
|
|
|
// Define a new Qi 'keyword' directive usable as a shortcut for a
|
|
// repository::distinct(char_(std::string("0-9a-zA-Z_")))
|
|
std::string const keyword_spec("0-9a-zA-Z_");
|
|
keyword_tag_type const keyword = distinct_spec(char_spec(keyword_spec));
|
|
//]
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int main()
|
|
{
|
|
using namespace spirit_test;
|
|
using namespace boost::spirit;
|
|
|
|
{
|
|
using namespace boost::spirit::ascii;
|
|
|
|
qi::rule<char const*, space_type> r;
|
|
r = distinct::keyword["description"] >> -lit(':') >> distinct::keyword["ident"];
|
|
|
|
BOOST_TEST(test("description ident", r, space));
|
|
BOOST_TEST(test("description:ident", r, space));
|
|
BOOST_TEST(test("description: ident", r, space));
|
|
BOOST_TEST(!test("descriptionident", r, space));
|
|
}
|
|
|
|
return boost::report_errors();
|
|
}
|
|
|