char_set.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 (get_case_compare<encoding>(context)(ch, from) >= 0)
  36. && (get_case_compare<encoding>(context)(ch , to) <= 0);
  37. }
  38. char_type from, to;
  39. };
  40. ///////////////////////////////////////////////////////////////////////////
  41. // Parser for a character set
  42. ///////////////////////////////////////////////////////////////////////////
  43. template <typename Encoding, typename Attribute = typename Encoding::char_type>
  44. struct char_set : char_parser<char_set<Encoding, Attribute>>
  45. {
  46. typedef typename Encoding::char_type char_type;
  47. typedef Encoding encoding;
  48. typedef Attribute attribute_type;
  49. static bool const has_attribute =
  50. !is_same<unused_type, attribute_type>::value;
  51. template <typename String>
  52. char_set(String const& str)
  53. {
  54. using spirit::x3::detail::cast_char;
  55. auto* definition = traits::get_c_string(str);
  56. auto ch = *definition++;
  57. while (ch)
  58. {
  59. auto next = *definition++;
  60. if (next == '-')
  61. {
  62. next = *definition++;
  63. if (next == 0)
  64. {
  65. chset.set(cast_char<char_type>(ch));
  66. chset.set('-');
  67. break;
  68. }
  69. chset.set(
  70. cast_char<char_type>(ch),
  71. cast_char<char_type>(next)
  72. );
  73. }
  74. else
  75. {
  76. chset.set(cast_char<char_type>(ch));
  77. }
  78. ch = next;
  79. }
  80. }
  81. template <typename Char, typename Context>
  82. bool test(Char ch_, Context const& context) const
  83. {
  84. return get_case_compare<encoding>(context).in_set(ch_, chset);
  85. }
  86. support::detail::basic_chset<char_type> chset;
  87. };
  88. template <typename Encoding, typename Attribute>
  89. struct get_info<char_set<Encoding, Attribute>>
  90. {
  91. typedef std::string result_type;
  92. std::string operator()(char_set<Encoding, Attribute> const& /* p */) const
  93. {
  94. return "char-set";
  95. }
  96. };
  97. template <typename Encoding, typename Attribute>
  98. struct get_info<char_range<Encoding, Attribute>>
  99. {
  100. typedef std::string result_type;
  101. std::string operator()(char_range<Encoding, Attribute> const& p) const
  102. {
  103. return "char_range \"" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '"';
  104. }
  105. };
  106. }}}
  107. #endif