Imported existing code
This commit is contained in:
369
libraries/include/boost/spirit/home/qi/char/char.hpp
Normal file
369
libraries/include/boost/spirit/home/qi/char/char.hpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/*=============================================================================
|
||||
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_CHAR_APR_16_2006_1051AM)
|
||||
#define BOOST_SPIRIT_CHAR_APR_16_2006_1051AM
|
||||
|
||||
#include <boost/spirit/home/qi/char/char_parser.hpp>
|
||||
#include <boost/spirit/home/qi/char/detail/get_char.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/include/value_at.hpp>
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/spirit/home/support/modifier.hpp>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/spirit/home/support/detail/to_narrow.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/mpl/print.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse any character
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct any_char : char_parser<any_char<Char>, Char>
|
||||
{
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const&, CharParam, Context&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return "any-char";
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse a single character
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct literal_char : char_parser<literal_char<Char>, Char>
|
||||
{
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type; // literal parsers have no attribute
|
||||
};
|
||||
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context&)
|
||||
{
|
||||
return detail::get_char(fusion::at_c<0>(component.elements)) == ch;
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return std::string("'")
|
||||
+ spirit::detail::to_narrow_char(
|
||||
detail::get_char(fusion::at_c<0>(component.elements)))
|
||||
+ '\'';
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse a character set
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct char_set : char_parser<char_set<Char>, Char>
|
||||
{
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context&)
|
||||
{
|
||||
return component.ptr->test(ch);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return "char-set";
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse a lazy character
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct lazy_char : char_parser<lazy_char>
|
||||
{
|
||||
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 CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context& context)
|
||||
{
|
||||
return fusion::at_c<0>(component.elements)(unused, context) == ch;
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return std::string("'")
|
||||
+ spirit::detail::to_narrow_char(
|
||||
fusion::at_c<0>(component.elements)(unused, ctx))
|
||||
+ '\'';
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse a character range
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct char_range : char_parser<char_range<Char>, Char>
|
||||
{
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context&)
|
||||
{
|
||||
return
|
||||
!(ch < fusion::at_c<0>(component.elements)) &&
|
||||
!(fusion::at_c<1>(component.elements) < ch);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
std::string result;
|
||||
result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
|
||||
result += "...";
|
||||
result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse a lazy character range
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct lazy_char_range : char_parser<lazy_char_range>
|
||||
{
|
||||
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 CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context& context)
|
||||
{
|
||||
return
|
||||
!(ch < fusion::at_c<0>(component.elements)(unused, context)) &&
|
||||
!(fusion::at_c<1>(component.elements)(unused, context) < ch);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return "char-range";
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// no_case literal_char version
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct no_case_literal_char : char_parser<no_case_literal_char<Char>, Char>
|
||||
{
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type; // literal parsers have no attribute
|
||||
};
|
||||
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context&)
|
||||
{
|
||||
return detail::get_char(fusion::at_c<0>(component.elements)) == ch
|
||||
|| detail::get_char(fusion::at_c<1>(component.elements)) == ch
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
std::string result;
|
||||
result += std::string("'")
|
||||
+ spirit::detail::to_narrow_char(
|
||||
detail::get_char(fusion::at_c<0>(component.elements))) + '\'';
|
||||
result += " or ";
|
||||
result += std::string("'") +
|
||||
spirit::detail::to_narrow_char(
|
||||
detail::get_char(fusion::at_c<1>(component.elements))) + '\'';
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// no_case char_range version
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct no_case_char_range : char_parser<no_case_char_range<Char>, Char>
|
||||
{
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context&)
|
||||
{
|
||||
return
|
||||
(!(ch < fusion::at_c<0>(component.elements)) &&
|
||||
!(fusion::at_c<1>(component.elements) < ch))
|
||||
|| (!(ch < fusion::at_c<2>(component.elements)) &&
|
||||
!(fusion::at_c<3>(component.elements) < ch))
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
std::string result;
|
||||
result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
|
||||
result += "...";
|
||||
result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
|
||||
result += " or ";
|
||||
result += std::string("'") + fusion::at_c<2>(component.elements) + '\'';
|
||||
result += "...";
|
||||
result += std::string("'") + fusion::at_c<3>(component.elements) + '\'';
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char, typename Elements>
|
||||
struct char_set_component;
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// char_set_component generator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char, typename Elements, typename Modifier>
|
||||
struct make_component<qi::domain, qi::char_set<Char>, Elements, Modifier
|
||||
, typename disable_if<
|
||||
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
||||
>::type
|
||||
> : mpl::identity<qi::char_set_component<Char, Elements> >
|
||||
{
|
||||
static qi::char_set_component<Char, Elements>
|
||||
call(Elements const& elements)
|
||||
{
|
||||
return qi::char_set_component<Char, Elements>(
|
||||
fusion::at_c<0>(elements));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// no_case char_set_component generator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename Domain, typename Elements, typename Modifier, typename Char
|
||||
>
|
||||
struct make_modified_component<
|
||||
Domain, qi::char_set<Char>, Elements, Modifier
|
||||
, typename enable_if<
|
||||
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef qi::char_set_component<Char, Elements> type;
|
||||
typedef typename Modifier::char_set char_set;
|
||||
|
||||
static type
|
||||
call(Elements const& elements)
|
||||
{
|
||||
return qi::char_set_component<Char, Elements>(
|
||||
fusion::at_c<0>(elements), char_set());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// no_case_literal_char generator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename Domain, typename Elements, typename Modifier, typename Char
|
||||
>
|
||||
struct make_modified_component<
|
||||
Domain, qi::literal_char<Char>, Elements, Modifier
|
||||
, typename enable_if<
|
||||
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef fusion::vector<Char, Char> vector_type;
|
||||
typedef
|
||||
component<qi::domain, qi::no_case_literal_char<Char>, vector_type>
|
||||
type;
|
||||
|
||||
static type
|
||||
call(Elements const& elements)
|
||||
{
|
||||
typedef typename Modifier::char_set char_set;
|
||||
|
||||
Char ch = qi::detail::get_char(fusion::at_c<0>(elements));
|
||||
vector_type v(
|
||||
char_set::tolower(ch)
|
||||
, char_set::toupper(ch)
|
||||
);
|
||||
return type(v);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// no_case_char_range generator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename Domain, typename Elements, typename Modifier, typename Char
|
||||
>
|
||||
struct make_modified_component<
|
||||
Domain, qi::char_range<Char>, Elements, Modifier
|
||||
, typename enable_if<
|
||||
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef fusion::vector<Char, Char, Char, Char> vector_type;
|
||||
typedef
|
||||
component<qi::domain, qi::no_case_char_range<Char>, vector_type>
|
||||
type;
|
||||
|
||||
static type
|
||||
call(Elements const& elements)
|
||||
{
|
||||
typedef typename Modifier::char_set char_set;
|
||||
|
||||
Char first = fusion::at_c<0>(elements);
|
||||
Char last = fusion::at_c<1>(elements);
|
||||
vector_type v(
|
||||
char_set::tolower(first)
|
||||
, char_set::tolower(last)
|
||||
, char_set::toupper(first)
|
||||
, char_set::toupper(last)
|
||||
);
|
||||
return type(v);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
93
libraries/include/boost/spirit/home/qi/char/char_class.hpp
Normal file
93
libraries/include/boost/spirit/home/qi/char/char_class.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*=============================================================================
|
||||
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_CHAR_CLASS_APR_16_2006_1051AM)
|
||||
#define BOOST_SPIRIT_CHAR_CLASS_APR_16_2006_1051AM
|
||||
|
||||
#include <boost/spirit/home/qi/char/char_parser.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/modifier.hpp>
|
||||
#include <boost/spirit/home/support/iso8859_1.hpp>
|
||||
#include <boost/spirit/home/support/ascii.hpp>
|
||||
#include <boost/spirit/home/support/standard.hpp>
|
||||
#include <boost/spirit/home/support/standard_wide.hpp>
|
||||
#include <boost/fusion/include/cons.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// generic isxxx parser (for alnum, alpha, graph, etc.)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Tag>
|
||||
struct char_class
|
||||
: char_parser<char_class<Tag>, typename Tag::char_set::char_type>
|
||||
{
|
||||
typedef typename Tag::char_set char_set;
|
||||
typedef typename Tag::char_class char_class_;
|
||||
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const&, CharParam ch, Context&)
|
||||
{
|
||||
using spirit::char_class::classify;
|
||||
return classify<char_set>::is(char_class_(), ch);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
typedef spirit::char_class::what<char_set> what_;
|
||||
return what_::is(char_class_());
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// no_case char_class conversions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
using spirit::char_class::key;
|
||||
using spirit::char_class::lower_case_tag;
|
||||
using spirit::char_class::upper_case_tag;
|
||||
using spirit::char_class::tag::alpha;
|
||||
|
||||
template <typename Tag>
|
||||
struct make_no_case_char_class :
|
||||
mpl::identity<qi::char_class<Tag> > {};
|
||||
|
||||
template <typename CharSet>
|
||||
struct make_no_case_char_class<lower_case_tag<CharSet> >
|
||||
: mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
|
||||
|
||||
template <typename CharSet>
|
||||
struct make_no_case_char_class<upper_case_tag<CharSet> >
|
||||
: mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
|
||||
}
|
||||
|
||||
template <
|
||||
typename Domain, typename Elements, typename Modifier, typename Tag
|
||||
>
|
||||
struct make_modified_component<
|
||||
Domain, qi::char_class<Tag>, Elements, Modifier
|
||||
, typename enable_if<
|
||||
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
|
||||
>::type
|
||||
>
|
||||
{
|
||||
typedef typename detail::make_no_case_char_class<Tag>::type director;
|
||||
typedef component<qi::domain, director, fusion::nil> type;
|
||||
|
||||
static type
|
||||
call(Elements const&)
|
||||
{
|
||||
return type(fusion::nil());
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
82
libraries/include/boost/spirit/home/qi/char/char_parser.hpp
Normal file
82
libraries/include/boost/spirit/home/qi/char/char_parser.hpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*=============================================================================
|
||||
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_CHAR_PARSER_APR_16_2006_0906AM)
|
||||
#define BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM
|
||||
|
||||
#include <string>
|
||||
#include <boost/spirit/home/qi/skip.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
|
||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Derived, typename Char = unused_type>
|
||||
struct char_parser
|
||||
{
|
||||
typedef Char char_type;
|
||||
|
||||
// if Char is unused_type, Derived must supply its own attribute metafunction
|
||||
template <typename Component, typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef Char 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);
|
||||
|
||||
if (first != last && Derived::test(component, *first, context))
|
||||
{
|
||||
qi::detail::assign_to(*first, attr);
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// char_parser subclasses are required to
|
||||
// implement test:
|
||||
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
bool test(Component const& component, CharParam ch, Context& context);
|
||||
};
|
||||
|
||||
template <typename Positive>
|
||||
struct negated_char_parser :
|
||||
char_parser<
|
||||
negated_char_parser<Positive>, typename Positive::director::char_type
|
||||
>
|
||||
{
|
||||
template <typename Component, typename CharParam, typename Context>
|
||||
static bool test(Component const& component, CharParam ch, Context& context)
|
||||
{
|
||||
return !Positive::director::test(
|
||||
fusion::at_c<0>(component.elements), ch, context);
|
||||
}
|
||||
|
||||
template <typename Component, typename Context>
|
||||
static std::string what(Component const& component, Context const& ctx)
|
||||
{
|
||||
return std::string("not ")
|
||||
+ Positive::director::what(fusion::at_c<0>(component.elements), ctx);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,244 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2008 Joel de Guzman
|
||||
Copyright (c) 2001-2003 Daniel Nuffer
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
|
||||
#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <bitset>
|
||||
#include <boost/spirit/home/qi/char/detail/range_run.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: basic character set implementation using range_run
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct basic_chset
|
||||
{
|
||||
basic_chset() {}
|
||||
basic_chset(basic_chset const& arg_)
|
||||
: rr(arg_.rr) {}
|
||||
|
||||
bool
|
||||
test(Char v) const
|
||||
{
|
||||
return rr.test(v);
|
||||
}
|
||||
|
||||
void
|
||||
set(Char from, Char to)
|
||||
{
|
||||
rr.set(range<Char>(from, to));
|
||||
}
|
||||
|
||||
void
|
||||
set(Char c)
|
||||
{
|
||||
rr.set(range<Char>(c, c));
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char from, Char to)
|
||||
{
|
||||
rr.clear(range<Char>(from, to));
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char c)
|
||||
{
|
||||
rr.clear(range<Char>(c, c));
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
rr.clear();
|
||||
}
|
||||
|
||||
void
|
||||
inverse()
|
||||
{
|
||||
basic_chset inv;
|
||||
inv.set(
|
||||
(std::numeric_limits<Char>::min)(),
|
||||
(std::numeric_limits<Char>::max)()
|
||||
);
|
||||
inv -= *this;
|
||||
swap(inv);
|
||||
}
|
||||
|
||||
void
|
||||
swap(basic_chset& x)
|
||||
{
|
||||
rr.swap(x.rr);
|
||||
}
|
||||
|
||||
|
||||
basic_chset&
|
||||
operator|=(basic_chset const& x)
|
||||
{
|
||||
typedef typename range_run<Char>::const_iterator const_iterator;
|
||||
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
|
||||
rr.set(*iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset&
|
||||
operator&=(basic_chset const& x)
|
||||
{
|
||||
basic_chset inv;
|
||||
inv.set(
|
||||
(std::numeric_limits<Char>::min)(),
|
||||
(std::numeric_limits<Char>::max)()
|
||||
);
|
||||
inv -= x;
|
||||
*this -= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset&
|
||||
operator-=(basic_chset const& x)
|
||||
{
|
||||
typedef typename range_run<Char>::const_iterator const_iterator;
|
||||
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
|
||||
rr.clear(*iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset&
|
||||
operator^=(basic_chset const& x)
|
||||
{
|
||||
basic_chset bma = x;
|
||||
bma -= *this;
|
||||
*this -= x;
|
||||
*this |= bma;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private: range_run<Char> rr;
|
||||
};
|
||||
|
||||
#if (CHAR_BIT == 8)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: specializations for 8 bit chars using std::bitset
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct basic_chset_8bit
|
||||
{
|
||||
basic_chset_8bit() {}
|
||||
basic_chset_8bit(basic_chset_8bit const& arg_)
|
||||
: bset(arg_.bset) {}
|
||||
|
||||
bool
|
||||
test(Char v) const
|
||||
{
|
||||
return bset.test((unsigned char)v);
|
||||
}
|
||||
|
||||
void
|
||||
set(Char from, Char to)
|
||||
{
|
||||
for (int i = from; i <= to; ++i)
|
||||
bset.set((unsigned char)i);
|
||||
}
|
||||
|
||||
void
|
||||
set(Char c)
|
||||
{
|
||||
bset.set((unsigned char)c);
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char from, Char to)
|
||||
{
|
||||
for (int i = from; i <= to; ++i)
|
||||
bset.reset((unsigned char)i);
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char c)
|
||||
{
|
||||
bset.reset((unsigned char)c);
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
bset.reset();
|
||||
}
|
||||
|
||||
void
|
||||
inverse()
|
||||
{
|
||||
bset.flip();
|
||||
}
|
||||
|
||||
void
|
||||
swap(basic_chset_8bit& x)
|
||||
{
|
||||
std::swap(bset, x.bset);
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator|=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset |= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator&=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset &= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator-=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset &= ~x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator^=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset ^= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private: std::bitset<256> bset;
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
struct basic_chset<char>
|
||||
: basic_chset_8bit<char> {};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
struct basic_chset<signed char>
|
||||
: basic_chset_8bit<signed char> {};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
struct basic_chset<unsigned char>
|
||||
: basic_chset_8bit<unsigned char> {};
|
||||
|
||||
#endif // #if (CHAR_BIT == 8)
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*=============================================================================
|
||||
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_GET_CHAR_APR_20_2008_0618_PM)
|
||||
#define BOOST_SPIRIT_GET_CHAR_APR_20_2008_0618_PM
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
// utility to get the (first) character from a primitive char,
|
||||
// a null terminated string and a std::basic_string
|
||||
|
||||
template <typename Char>
|
||||
static Char get_char(Char ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static Char get_char(Char const* str)
|
||||
{
|
||||
return *str;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static Char get_char(std::basic_string<Char> const& str)
|
||||
{
|
||||
return str[0];
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
35
libraries/include/boost/spirit/home/qi/char/detail/range.hpp
Normal file
35
libraries/include/boost/spirit/home/qi/char/detail/range.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_MAY_16_2006_0720_PM)
|
||||
#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// A closed range (first, last)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct range
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
range()
|
||||
: first(), last()
|
||||
{
|
||||
}
|
||||
|
||||
range(T first, T last)
|
||||
: first(first), last(last)
|
||||
{
|
||||
}
|
||||
|
||||
T first;
|
||||
T last;
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)
|
||||
#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM
|
||||
|
||||
#include <boost/integer_traits.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Range>
|
||||
inline bool
|
||||
is_valid(Range const& range)
|
||||
{
|
||||
// test for valid ranges
|
||||
return range.first <= range.last;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline bool
|
||||
includes(Range const& range, Range const& other)
|
||||
{
|
||||
// see if two ranges intersect
|
||||
return (range.first <= other.first) && (range.last >= other.last);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline bool
|
||||
includes(Range const& range, typename Range::value_type val)
|
||||
{
|
||||
// see if val is in range
|
||||
return (range.first <= val) && (range.last >= val);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline bool
|
||||
can_merge(Range const& range, Range const& other)
|
||||
{
|
||||
// see if a 'range' overlaps, or is adjacent to
|
||||
// another range 'other', so we can merge them
|
||||
|
||||
typedef typename Range::value_type value_type;
|
||||
typedef integer_traits<value_type> integer_traits;
|
||||
|
||||
value_type decr_first =
|
||||
range.first == integer_traits::const_min
|
||||
? range.first : range.first-1;
|
||||
|
||||
value_type incr_last =
|
||||
range.last == integer_traits::const_max
|
||||
? range.last : range.last+1;
|
||||
|
||||
return (decr_first <= other.last) && (incr_last >= other.first);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline void
|
||||
merge(Range& result, Range const& other)
|
||||
{
|
||||
// merge two ranges
|
||||
if (result.first > other.first)
|
||||
result.first = other.first;
|
||||
if (result.last < other.last)
|
||||
result.last = other.last;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
struct range_compare
|
||||
{
|
||||
// compare functor with a value or another range
|
||||
|
||||
typedef typename Range::value_type value_type;
|
||||
|
||||
bool operator()(Range const& x, const value_type y) const
|
||||
{
|
||||
return x.first < y;
|
||||
}
|
||||
|
||||
bool operator()(value_type const x, Range const& y) const
|
||||
{
|
||||
return x < y.first;
|
||||
}
|
||||
|
||||
bool operator()(Range const& x, Range const& y) const
|
||||
{
|
||||
return x.first < y.first;
|
||||
}
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_RUN_MAY_16_2006_0801_PM)
|
||||
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM
|
||||
|
||||
#include <boost/spirit/home/qi/char/detail/range.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// range_run
|
||||
//
|
||||
// An implementation of a sparse bit (boolean) set. The set uses
|
||||
// a sorted vector of disjoint ranges. This class implements the
|
||||
// bare minimum essentials from which the full range of set
|
||||
// operators can be implemented. The set is constructed from
|
||||
// ranges. Internally, adjacent or overlapping ranges are
|
||||
// coalesced.
|
||||
//
|
||||
// range_runs are very space-economical in situations where there
|
||||
// are lots of ranges and a few individual disjoint values.
|
||||
// Searching is O(log n) where n is the number of ranges.
|
||||
//
|
||||
// { Low level interface }
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
class range_run
|
||||
{
|
||||
public:
|
||||
|
||||
typedef range<Char> range_type;
|
||||
typedef std::vector<range_type> storage_type;
|
||||
|
||||
void swap(range_run& other);
|
||||
bool test(Char v) const;
|
||||
void set(range_type const& range);
|
||||
void clear(range_type const& range);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
storage_type run;
|
||||
};
|
||||
}}}}
|
||||
|
||||
#include <boost/spirit/home/qi/char/detail/range_run_impl.hpp>
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_RUN_MAY_16_2006_0807_PM)
|
||||
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
|
||||
|
||||
#include <boost/spirit/home/qi/char/detail/range_functions.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Run, typename Iterator, typename Range>
|
||||
inline bool
|
||||
try_merge(Run& run, Iterator iter, Range const& range)
|
||||
{
|
||||
// if *iter intersects with, or is adjacent to, 'range'...
|
||||
if (can_merge(*iter, range))
|
||||
{
|
||||
typedef typename Range::value_type value_type;
|
||||
typedef integer_traits<value_type> integer_traits;
|
||||
|
||||
// merge range and *iter
|
||||
merge(*iter, range);
|
||||
|
||||
// collapse all subsequent ranges that can merge with *iter
|
||||
Iterator i;
|
||||
value_type last =
|
||||
iter->last == integer_traits::const_max
|
||||
? iter->last : iter->last+1;
|
||||
|
||||
for (i = iter+1; i != run.end() && last >= i->first; ++i)
|
||||
{
|
||||
iter->last = i->last;
|
||||
}
|
||||
// erase all ranges that were collapsed
|
||||
run.erase(iter+1, i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline bool
|
||||
range_run<Char>::test(Char val) const
|
||||
{
|
||||
if (run.empty())
|
||||
return false;
|
||||
|
||||
// search the ranges for one that potentially includes val
|
||||
typename storage_type::const_iterator iter =
|
||||
std::upper_bound(
|
||||
run.begin(), run.end(), val,
|
||||
range_compare<range_type>()
|
||||
);
|
||||
|
||||
// return true if *(iter-1) includes val
|
||||
return iter != run.begin() && includes(*(--iter), val);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void
|
||||
range_run<Char>::swap(range_run& other)
|
||||
{
|
||||
run.swap(other.run);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void
|
||||
range_run<Char>::set(range_type const& range)
|
||||
{
|
||||
BOOST_ASSERT(is_valid(range));
|
||||
if (run.empty())
|
||||
{
|
||||
// the vector is empty, insert 'range'
|
||||
run.push_back(range);
|
||||
return;
|
||||
}
|
||||
|
||||
// search the ranges for one that potentially includes 'range'
|
||||
typename storage_type::iterator iter =
|
||||
std::upper_bound(
|
||||
run.begin(), run.end(), range,
|
||||
range_compare<range_type>()
|
||||
);
|
||||
|
||||
if (iter != run.begin())
|
||||
{
|
||||
// if *(iter-1) includes 'range', return early
|
||||
if (includes(*(iter-1), range))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if *(iter-1) can merge with 'range', merge them and return
|
||||
if (try_merge(run, iter-1, range))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if *iter can merge with with 'range', merge them
|
||||
if (iter == run.end() || !try_merge(run, iter, range))
|
||||
{
|
||||
// no overlap, insert 'range'
|
||||
run.insert(iter, range);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void
|
||||
range_run<Char>::clear(range_type const& range)
|
||||
{
|
||||
BOOST_ASSERT(is_valid(range));
|
||||
if (!run.empty())
|
||||
{
|
||||
// search the ranges for one that potentially includes 'range'
|
||||
typename storage_type::iterator iter =
|
||||
std::upper_bound(
|
||||
run.begin(), run.end(), range,
|
||||
range_compare<range_type>()
|
||||
);
|
||||
|
||||
typename storage_type::iterator left_iter;
|
||||
|
||||
// if *(iter-1) includes the 'range.first',
|
||||
if ((iter != run.begin()) &&
|
||||
includes(*(left_iter = (iter-1)), range.first))
|
||||
{
|
||||
// if the 'range' is in the middle,
|
||||
if (left_iter->last > range.last)
|
||||
{
|
||||
// break it apart into two ranges (punch a hole)
|
||||
Char save_last = left_iter->last;
|
||||
left_iter->last = range.first-1;
|
||||
run.insert(iter, range_type(range.last+1, save_last));
|
||||
return;
|
||||
}
|
||||
else // if it is not in the middle,
|
||||
{
|
||||
// truncate it (clip its right)
|
||||
left_iter->last = range.first-1;
|
||||
}
|
||||
}
|
||||
|
||||
// position i to the first range that 'range'
|
||||
// does not intersect with
|
||||
typename storage_type::iterator i = iter;
|
||||
while (i != run.end() && includes(range, *i))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
// if *i includes 'range.last', truncate it (clip its left)
|
||||
if (i != run.end() && includes(*i, range.last))
|
||||
{
|
||||
i->first = range.last+1;
|
||||
}
|
||||
|
||||
// cleanup... erase all subsequent ranges that the
|
||||
// 'range' includes
|
||||
run.erase(iter, i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void
|
||||
range_run<Char>::clear()
|
||||
{
|
||||
run.clear();
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
396
libraries/include/boost/spirit/home/qi/char/meta_grammar.hpp
Normal file
396
libraries/include/boost/spirit/home/qi/char/meta_grammar.hpp
Normal file
@@ -0,0 +1,396 @@
|
||||
/*=============================================================================
|
||||
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_META_GRAMMAR_FEB_02_2007_0925AM)
|
||||
#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/placeholders.hpp>
|
||||
#include <boost/spirit/home/support/meta_grammar.hpp>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/spirit/home/qi/char/detail/basic_chset.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// forwards
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct any_char;
|
||||
|
||||
template <typename Char>
|
||||
struct literal_char;
|
||||
|
||||
struct lazy_char;
|
||||
|
||||
template <typename Char>
|
||||
struct char_range;
|
||||
|
||||
struct lazy_char_range;
|
||||
|
||||
template <typename Positive>
|
||||
struct negated_char_parser;
|
||||
|
||||
template <typename Tag>
|
||||
struct char_class;
|
||||
|
||||
struct char_meta_grammar;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Enable>
|
||||
struct is_valid_expr;
|
||||
|
||||
template <typename Expr, typename Enable>
|
||||
struct expr_transform;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get the director of an any_char
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Tag>
|
||||
struct extract_any_char_director;
|
||||
|
||||
template <>
|
||||
struct extract_any_char_director<tag::char_>
|
||||
{
|
||||
typedef any_char<char> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct extract_any_char_director<tag::wchar>
|
||||
{
|
||||
typedef any_char<wchar_t> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get the director of a character literal type
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Tag, typename T>
|
||||
struct extract_literal_char_director;
|
||||
|
||||
template <typename T>
|
||||
struct extract_literal_char_director<tag::char_, T>
|
||||
{
|
||||
typedef literal_char<T> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_literal_char_director<tag::wchar, T>
|
||||
{
|
||||
typedef literal_char<wchar_t> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_literal_char_director<tag::lit, T>
|
||||
{
|
||||
typedef literal_char<T> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_literal_char_director<tag::wlit, T>
|
||||
{
|
||||
typedef literal_char<wchar_t> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get the director of a character range type
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Tag, typename T>
|
||||
struct extract_char_range_director;
|
||||
|
||||
template <typename T>
|
||||
struct extract_char_range_director<tag::char_, T>
|
||||
{
|
||||
typedef char_range<T> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_char_range_director<tag::wchar, T>
|
||||
{
|
||||
typedef char_range<wchar_t> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// char parser meta-grammars
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// literals: 'x', L'x'
|
||||
struct basic_char_literal_meta_grammar
|
||||
: proto::or_<
|
||||
proto::terminal<char>
|
||||
, proto::terminal<wchar_t>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// literals: 'x', L'x' and single char strings: "x", L"x"
|
||||
struct single_char_literal_meta_grammar
|
||||
: proto::or_<
|
||||
// plain chars:
|
||||
proto::terminal<char>
|
||||
, proto::terminal<wchar_t>
|
||||
// single char null terminates strings:
|
||||
, proto::terminal<char[2]>
|
||||
, proto::terminal<char(&)[2]>
|
||||
, proto::terminal<wchar_t[2]>
|
||||
, proto::terminal<wchar_t(&)[2]>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// literals: 'x', L'x'
|
||||
struct char_literal_meta_grammar
|
||||
: proto::or_<
|
||||
meta_grammar::terminal_rule<
|
||||
qi::domain, char, literal_char<char>
|
||||
>
|
||||
, meta_grammar::terminal_rule<
|
||||
qi::domain, wchar_t, literal_char<wchar_t>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// literal strings: "hello" (defined in qi/string/meta_grammar.hpp)
|
||||
struct basic_string_literal_meta_grammar;
|
||||
|
||||
// std::string(s) (defined in qi/string/meta_grammar.hpp)
|
||||
struct basic_std_string_meta_grammar;
|
||||
|
||||
template <typename T>
|
||||
struct extract_char; // (defined in qi/string/metagrammar.hpp)
|
||||
|
||||
template <typename Tag, typename T>
|
||||
struct extract_chset_director;
|
||||
|
||||
template <typename T>
|
||||
struct extract_chset_director<tag::char_, T>
|
||||
{
|
||||
typedef typename extract_char<T>::type char_type;
|
||||
typedef char_set<char_type> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct extract_chset_director<tag::wchar, T>
|
||||
{
|
||||
typedef typename extract_char<T>::type char_type;
|
||||
typedef char_set<char_type> type;
|
||||
};
|
||||
|
||||
template <typename Char, typename Elements>
|
||||
struct char_set_component
|
||||
{
|
||||
typedef qi::domain domain;
|
||||
typedef char_set<Char> director;
|
||||
typedef Elements elements_type;
|
||||
|
||||
char_set_component(Char const* definition)
|
||||
: ptr(new detail::basic_chset<Char>())
|
||||
{
|
||||
Char ch = *definition++;
|
||||
while (ch)
|
||||
{
|
||||
Char next = *definition++;
|
||||
if (next == '-')
|
||||
{
|
||||
next = *definition++;
|
||||
if (next == 0)
|
||||
{
|
||||
ptr->set(ch);
|
||||
ptr->set('-');
|
||||
break;
|
||||
}
|
||||
ptr->set(ch, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->set(ch);
|
||||
}
|
||||
ch = next;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharSetClass> // no-case version
|
||||
char_set_component(Char const* definition, CharSetClass)
|
||||
: ptr(new detail::basic_chset<Char>())
|
||||
{
|
||||
Char ch = *definition++;
|
||||
while (ch)
|
||||
{
|
||||
Char next = *definition++;
|
||||
if (next == '-')
|
||||
{
|
||||
next = *definition++;
|
||||
if (next == 0)
|
||||
{
|
||||
ptr->set(CharSetClass::tolower(ch));
|
||||
ptr->set(CharSetClass::tolower('-'));
|
||||
ptr->set(CharSetClass::toupper(ch));
|
||||
ptr->set(CharSetClass::toupper('-'));
|
||||
break;
|
||||
}
|
||||
ptr->set(CharSetClass::tolower(ch)
|
||||
, CharSetClass::tolower(next));
|
||||
ptr->set(CharSetClass::toupper(ch)
|
||||
, CharSetClass::toupper(next));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->set(CharSetClass::tolower(ch));
|
||||
ptr->set(CharSetClass::toupper(ch));
|
||||
}
|
||||
ch = next;
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<detail::basic_chset<Char> > ptr;
|
||||
};
|
||||
|
||||
// char_, char_('x'), char_("x"), char_(f), char_('x', 'z'),
|
||||
// char_(L'x'), char_(L'x', L'z'),
|
||||
// wchar, wchar('x'), wchar("x"), wchar('x', 'z'),
|
||||
// wchar(L'x'), wchar(L'x', L'z')
|
||||
// char_("a-z"), wchar("a-z")
|
||||
// [w]lit('x'), [w]lit(L'x')
|
||||
struct char_meta_grammar1
|
||||
: proto::or_<
|
||||
// char_, wchar --> any_char
|
||||
meta_grammar::compose_empty<
|
||||
proto::if_<
|
||||
is_char_tag<proto::_child, qi::domain>()
|
||||
>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_any_char_director<mpl::_> >
|
||||
>
|
||||
// char_('x'), wchar(L'x'), char_("x"), wchar(L"x")--> literal_char
|
||||
, meta_grammar::compose_function1_eval<
|
||||
proto::function<
|
||||
proto::if_<
|
||||
is_char_tag<proto::_child, qi::domain>()
|
||||
>
|
||||
, single_char_literal_meta_grammar
|
||||
>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
|
||||
>
|
||||
// lit("x"), wlit(L"x") --> literal_char
|
||||
, meta_grammar::compose_function1_eval<
|
||||
proto::function<
|
||||
proto::if_<
|
||||
is_lit_tag<proto::_child, qi::domain>()
|
||||
>
|
||||
, basic_char_literal_meta_grammar
|
||||
>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
|
||||
>
|
||||
// char_("a-z"), char_(L"a-z"), wchar(L"a-z") --> char_set
|
||||
, meta_grammar::compose_function1_eval<
|
||||
proto::function<
|
||||
proto::if_<
|
||||
is_char_tag<proto::_child, qi::domain>()>
|
||||
, proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
|
||||
>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_chset_director<mpl::_, mpl::_> >
|
||||
>
|
||||
// char_(F()) --> lazy_char
|
||||
, meta_grammar::function1_rule<
|
||||
qi::domain
|
||||
, tag::char_
|
||||
, lazy_char
|
||||
>
|
||||
// char_('x', 'z'), wchar(L'x', L'z') --> char_range
|
||||
, meta_grammar::compose_function2_eval<
|
||||
proto::function<
|
||||
proto::if_<
|
||||
is_char_tag<proto::_child, qi::domain>()
|
||||
>
|
||||
, basic_char_literal_meta_grammar
|
||||
, basic_char_literal_meta_grammar
|
||||
>
|
||||
, qi::domain
|
||||
, mpl::identity<extract_char_range_director<mpl::_, mpl::_> >
|
||||
>
|
||||
// char_(F1(), F2()) --> lazy_char_range
|
||||
, meta_grammar::function2_rule<
|
||||
qi::domain
|
||||
, tag::char_
|
||||
, lazy_char_range
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// char_classes: alnum, alpha, cntrl, ... etc.
|
||||
struct char_class_meta_grammar
|
||||
: proto::or_<
|
||||
// alnum, alpha, cntrl, ... etc.
|
||||
meta_grammar::compose_empty<
|
||||
proto::terminal<spirit::char_class::key<proto::_, proto::_> >
|
||||
, qi::domain
|
||||
, char_class<mpl::_>
|
||||
>
|
||||
, meta_grammar::compose_empty<
|
||||
proto::terminal<spirit::char_class::lower_case_tag<proto::_> >
|
||||
, qi::domain
|
||||
, char_class<mpl::_>
|
||||
>
|
||||
, meta_grammar::compose_empty<
|
||||
proto::terminal<spirit::char_class::upper_case_tag<proto::_> >
|
||||
, qi::domain
|
||||
, char_class<mpl::_>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
// ~x (where x is a char_parser)
|
||||
struct negated_char_meta_grammar
|
||||
: meta_grammar::compose_single<
|
||||
proto::unary_expr<
|
||||
proto::tag::complement
|
||||
, char_meta_grammar
|
||||
>
|
||||
, qi::domain
|
||||
, negated_char_parser<mpl::_>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// main char_meta_grammar
|
||||
struct char_meta_grammar
|
||||
: proto::or_<
|
||||
char_meta_grammar1
|
||||
, char_class_meta_grammar
|
||||
, char_literal_meta_grammar
|
||||
, negated_char_meta_grammar
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// These specializations non-intrusively hooks into the RD meta-grammar.
|
||||
// (see qi/meta_grammar.hpp)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct is_valid_expr<Expr
|
||||
, typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct expr_transform<Expr
|
||||
, typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
|
||||
: mpl::identity<char_meta_grammar>
|
||||
{
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user