char_set.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM)
  7. #define BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM
  8. #include <boost/spirit/home/x3/char/char_parser.hpp>
  9. #include <boost/spirit/home/x3/char/detail/cast_char.hpp>
  10. #include <boost/spirit/home/x3/support/traits/string_traits.hpp>
  11. #include <boost/spirit/home/x3/support/utility/utf8.hpp>
  12. #include <boost/spirit/home/x3/support/no_case.hpp>
  13. #include <boost/spirit/home/support/char_set/basic_chset.hpp>
  14. #include <boost/type_traits/is_same.hpp>
  15. namespace boost { namespace spirit { namespace x3
  16. {
  17. ///////////////////////////////////////////////////////////////////////////
  18. // Parser for a character range
  19. ///////////////////////////////////////////////////////////////////////////
  20. template <typename Encoding, typename Attribute = typename Encoding::char_type>
  21. struct char_range
  22. : char_parser< char_range<Encoding, Attribute> >
  23. {
  24. typedef typename Encoding::char_type char_type;
  25. typedef Encoding encoding;
  26. typedef Attribute attribute_type;
  27. static bool const has_attribute =
  28. !is_same<unused_type, attribute_type>::value;
  29. char_range(char_type from_, char_type to_)
  30. : from(from_), to(to_) {}
  31. template <typename Char, typename Context>
  32. bool test(Char ch_, Context const& context) const
  33. {
  34. char_type ch = char_type(ch_); // optimize for token based parsing
  35. return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
  36. && (get_case_compare<encoding>(context)(ch, from) >= 0 )
  37. && (get_case_compare<encoding>(context)(ch , to) <= 0 );
  38. }
  39. char_type from, to;
  40. };
  41. ///////////////////////////////////////////////////////////////////////////
  42. // Parser for a character set
  43. ///////////////////////////////////////////////////////////////////////////
  44. template <typename Encoding, typename Attribute = typename Encoding::char_type>
  45. struct char_set : char_parser<char_set<Encoding, Attribute>>
  46. {
  47. typedef typename Encoding::char_type char_type;
  48. typedef Encoding encoding;
  49. typedef Attribute attribute_type;
  50. static bool const has_attribute =
  51. !is_same<unused_type, attribute_type>::value;
  52. template <typename String>
  53. char_set(String const& str)
  54. {
  55. using spirit::x3::detail::cast_char;
  56. typedef typename
  57. remove_const<
  58. typename traits::char_type_of<String>::type
  59. >::type
  60. in_type;
  61. in_type const* definition =
  62. (in_type const*)traits::get_c_string(str);
  63. in_type ch = *definition++;
  64. while (ch)
  65. {
  66. in_type next = *definition++;
  67. if (next == '-')
  68. {
  69. next = *definition++;
  70. if (next == 0)
  71. {
  72. chset.set(cast_char<char_type>(ch));
  73. chset.set('-');
  74. break;
  75. }
  76. chset.set(
  77. cast_char<char_type>(ch),
  78. cast_char<char_type>(next)
  79. );
  80. }
  81. else
  82. {
  83. chset.set(cast_char<char_type>(ch));
  84. }
  85. ch = next;
  86. }
  87. }
  88. template <typename Char, typename Context>
  89. bool test(Char ch_, Context const& context) const
  90. {
  91. return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
  92. && get_case_compare<encoding>(context).in_set(ch_,chset);
  93. }
  94. support::detail::basic_chset<char_type> chset;
  95. };
  96. template <typename Encoding, typename Attribute>
  97. struct get_info<char_set<Encoding, Attribute>>
  98. {
  99. typedef std::string result_type;
  100. std::string operator()(char_set<Encoding, Attribute> const& /* p */) const
  101. {
  102. return "char-set";
  103. }
  104. };
  105. template <typename Encoding, typename Attribute>
  106. struct get_info<char_range<Encoding, Attribute>>
  107. {
  108. typedef std::string result_type;
  109. std::string operator()(char_range<Encoding, Attribute> const& p) const
  110. {
  111. return "char_range \"" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '"';
  112. }
  113. };
  114. }}}
  115. #endif