205 lines
7.0 KiB
C++
Executable File
205 lines
7.0 KiB
C++
Executable File
/*=============================================================================
|
|
Copyright (c) 2001-2007 Joel de Guzman
|
|
|
|
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)
|
|
==============================================================================*/
|
|
#if !defined(BOOST_SPIRIT_LIT_APR_18_2006_1125PM)
|
|
#define BOOST_SPIRIT_LIT_APR_18_2006_1125PM
|
|
|
|
#include <boost/spirit/home/qi/domain.hpp>
|
|
#include <boost/spirit/home/qi/skip.hpp>
|
|
#include <boost/spirit/home/qi/detail/string_parse.hpp>
|
|
#include <boost/spirit/home/support/char_class.hpp>
|
|
#include <boost/spirit/home/support/modifier.hpp>
|
|
#include <boost/spirit/home/support/unused.hpp>
|
|
#include <boost/spirit/home/support/detail/to_narrow.hpp>
|
|
#include <boost/fusion/include/at.hpp>
|
|
#include <boost/fusion/include/value_at.hpp>
|
|
#include <boost/fusion/include/vector.hpp>
|
|
#include <boost/type_traits/remove_reference.hpp>
|
|
#include <string>
|
|
|
|
namespace boost { namespace spirit { namespace qi
|
|
{
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// parse literal strings
|
|
///////////////////////////////////////////////////////////////////////////
|
|
template <typename Char>
|
|
struct literal_string
|
|
{
|
|
template <typename Component, typename Context, typename Iterator>
|
|
struct attribute
|
|
{
|
|
typedef unused_type type; // literal parsers have no attribute
|
|
};
|
|
|
|
template <
|
|
typename Component
|
|
, typename Iterator, typename Context
|
|
, typename Skipper, typename Attribute>
|
|
static bool parse(
|
|
Component const& component
|
|
, Iterator& first, Iterator const& last
|
|
, Context& /*context*/, Skipper const& skipper
|
|
, Attribute& attr)
|
|
{
|
|
qi::skip(first, last, skipper);
|
|
return detail::string_parse(
|
|
fusion::at_c<0>(component.elements)
|
|
, first
|
|
, last
|
|
, attr
|
|
);
|
|
}
|
|
|
|
template <typename Component, typename Context>
|
|
static std::string what(Component const& component, Context const& ctx)
|
|
{
|
|
return std::string("\"")
|
|
+ spirit::detail::to_narrow_string(
|
|
fusion::at_c<0>(component.elements))
|
|
+ std::string("\"")
|
|
;
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// parse lazy strings
|
|
///////////////////////////////////////////////////////////////////////////
|
|
struct lazy_string
|
|
{
|
|
template <typename Component, typename Context, typename Iterator>
|
|
struct attribute
|
|
{
|
|
typedef typename
|
|
result_of::subject<Component>::type
|
|
subject_type;
|
|
|
|
typedef typename
|
|
remove_reference<
|
|
typename boost::result_of<subject_type(unused_type, Context)>::type
|
|
>::type
|
|
type;
|
|
};
|
|
|
|
template <
|
|
typename Component
|
|
, typename Iterator, typename Context
|
|
, typename Skipper, typename Attribute>
|
|
static bool parse(
|
|
Component const& component
|
|
, Iterator& first, Iterator const& last
|
|
, Context& context, Skipper const& skipper
|
|
, Attribute& attr)
|
|
{
|
|
qi::skip(first, last, skipper);
|
|
return detail::string_parse(
|
|
fusion::at_c<0>(component.elements)(unused, context)
|
|
, first
|
|
, last
|
|
, attr
|
|
);
|
|
}
|
|
|
|
template <typename Component, typename Context>
|
|
static std::string what(Component const& component, Context const& ctx)
|
|
{
|
|
return std::string("\"")
|
|
+ spirit::detail::to_narrow_string(
|
|
fusion::at_c<0>(component.elements)(unused, ctx))
|
|
+ std::string("\"")
|
|
;
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// no_case literal_string version
|
|
///////////////////////////////////////////////////////////////////////////
|
|
template <typename Char>
|
|
struct no_case_literal_string
|
|
{
|
|
template <typename Component, typename Context, typename Iterator>
|
|
struct attribute
|
|
{
|
|
typedef unused_type type; // literal parsers have no attribute
|
|
};
|
|
|
|
template <
|
|
typename Component
|
|
, typename Iterator, typename Context
|
|
, typename Skipper, typename Attribute>
|
|
static bool parse(
|
|
Component const& component
|
|
, Iterator& first, Iterator const& last
|
|
, Context& /*context*/, Skipper const& skipper
|
|
, Attribute& attr)
|
|
{
|
|
qi::skip(first, last, skipper);
|
|
return detail::string_parse(
|
|
fusion::at_c<0>(component.elements)
|
|
, fusion::at_c<1>(component.elements)
|
|
, first
|
|
, last
|
|
, attr
|
|
);
|
|
}
|
|
|
|
template <typename Component, typename Context>
|
|
static std::string what(Component const& component, Context const& ctx)
|
|
{
|
|
return std::string("case-insensitive \"")
|
|
+ spirit::detail::to_narrow_string(
|
|
fusion::at_c<0>(component.elements))
|
|
+ std::string("\"")
|
|
;
|
|
}
|
|
};
|
|
}}}
|
|
|
|
namespace boost { namespace spirit { namespace traits
|
|
{
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// no_case_literal_string generator
|
|
///////////////////////////////////////////////////////////////////////////
|
|
template <
|
|
typename Domain, typename Elements, typename Modifier, typename Char
|
|
>
|
|
struct make_modified_component<
|
|
Domain, qi::literal_string<Char>, Elements, Modifier
|
|
, typename enable_if<
|
|
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
|
>::type
|
|
>
|
|
{
|
|
typedef std::basic_string<Char> string_type;
|
|
typedef fusion::vector<string_type, string_type> vector_type;
|
|
typedef
|
|
component<qi::domain, qi::no_case_literal_string<Char>, vector_type>
|
|
type;
|
|
|
|
static type
|
|
call(Elements const& elements)
|
|
{
|
|
typedef typename Modifier::char_set char_set;
|
|
|
|
Char const* in = fusion::at_c<0>(elements);
|
|
string_type lo(in);
|
|
string_type hi(in);
|
|
|
|
typename string_type::iterator loi = lo.begin();
|
|
typename string_type::iterator hii = hi.begin();
|
|
|
|
for (; loi != lo.end(); ++loi, ++hii, ++in)
|
|
{
|
|
*loi = char_set::tolower(*loi);
|
|
*hii = char_set::toupper(*hii);
|
|
}
|
|
|
|
return type(vector_type(lo, hi));
|
|
}
|
|
};
|
|
}}}
|
|
|
|
#endif
|