escape_char.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*=============================================================================
  2. Copyright (c) 2001-2003 Daniel Nuffer
  3. http://spirit.sourceforge.net/
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #ifndef BOOST_SPIRIT_ESCAPE_CHAR_HPP
  8. #define BOOST_SPIRIT_ESCAPE_CHAR_HPP
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include <string>
  11. #include <iterator>
  12. #include <cctype>
  13. #include <boost/limits.hpp>
  14. #include <boost/spirit/home/classic/namespace.hpp>
  15. #include <boost/spirit/home/classic/debug.hpp>
  16. #include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
  17. #include <boost/spirit/home/classic/utility/impl/escape_char.ipp>
  18. ///////////////////////////////////////////////////////////////////////////////
  19. namespace boost { namespace spirit {
  20. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  21. ///////////////////////////////////////////////////////////////////////////////
  22. //
  23. // escape_char_action class
  24. //
  25. // Links an escape char parser with a user defined semantic action.
  26. // The semantic action may be a function or a functor. A function
  27. // should be compatible with the interface:
  28. //
  29. // void f(CharT ch);
  30. //
  31. // A functor should have a member operator() with a compatible signature
  32. // as above. The matching character is passed into the function/functor.
  33. // This is the default class that character parsers use when dealing with
  34. // the construct:
  35. //
  36. // p[f]
  37. //
  38. // where p is a parser and f is a function or functor.
  39. //
  40. ///////////////////////////////////////////////////////////////////////////////
  41. template <
  42. typename ParserT, typename ActionT,
  43. unsigned long Flags, typename CharT
  44. >
  45. struct escape_char_action
  46. : public unary<ParserT,
  47. parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
  48. {
  49. typedef escape_char_action
  50. <ParserT, ActionT, Flags, CharT> self_t;
  51. typedef action_parser_category parser_category_t;
  52. typedef unary<ParserT, parser<self_t> > base_t;
  53. template <typename ScannerT>
  54. struct result
  55. {
  56. typedef typename match_result<ScannerT, CharT>::type type;
  57. };
  58. escape_char_action(ParserT const& p, ActionT const& a)
  59. : base_t(p), actor(a) {}
  60. template <typename ScannerT>
  61. typename parser_result<self_t, ScannerT>::type
  62. parse(ScannerT const& scan) const
  63. {
  64. return impl::escape_char_action_parse<Flags, CharT>::
  65. parse(scan, *this);
  66. }
  67. ActionT const& predicate() const { return actor; }
  68. private:
  69. ActionT actor;
  70. };
  71. ///////////////////////////////////////////////////////////////////////////////
  72. //
  73. // escape_char_parser class
  74. //
  75. // The escape_char_parser helps in conjunction with the escape_char_action
  76. // template class (see above) in parsing escaped characters. There are two
  77. // different variants of this parser: one for parsing C style escaped
  78. // characters and one for parsing LEX style escaped characters.
  79. //
  80. // The C style escaped character parser is generated, when the template
  81. // parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
  82. // file impl/escape_char.ipp). This parser recognizes all valid C escape
  83. // character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
  84. // and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
  85. // and converts these to their character equivalent, for instance the
  86. // sequence of a backslash and a 'b' is parsed as the character '\b'.
  87. // All other escaped characters are rejected by this parser.
  88. //
  89. // The LEX style escaped character parser is generated, when the template
  90. // parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
  91. // file impl/escape_char.ipp). This parser recognizes all the C style
  92. // escaped character sequences (as described above) and additionally
  93. // does not reject all other escape sequences. All not mentioned escape
  94. // sequences are converted by the parser to the plain character, for
  95. // instance '\a' will be parsed as 'a'.
  96. //
  97. // All not escaped characters are parsed without modification.
  98. //
  99. ///////////////////////////////////////////////////////////////////////////////
  100. template <unsigned long Flags, typename CharT>
  101. struct escape_char_action_parser_gen;
  102. template <unsigned long Flags, typename CharT>
  103. struct escape_char_parser :
  104. public parser<escape_char_parser<Flags, CharT> > {
  105. // only the values c_escapes and lex_escapes are valid for Flags
  106. BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
  107. typedef escape_char_parser<Flags, CharT> self_t;
  108. typedef
  109. escape_char_action_parser_gen<Flags, CharT>
  110. action_parser_generator_t;
  111. template <typename ScannerT>
  112. struct result {
  113. typedef typename match_result<ScannerT, CharT>::type type;
  114. };
  115. template <typename ActionT>
  116. escape_char_action<self_t, ActionT, Flags, CharT>
  117. operator[](ActionT const& actor) const
  118. {
  119. return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
  120. }
  121. template <typename ScannerT>
  122. typename parser_result<self_t, ScannerT>::type
  123. parse(ScannerT const &scan) const
  124. {
  125. return impl::escape_char_parse<CharT>::parse(scan, *this);
  126. }
  127. };
  128. template <unsigned long Flags, typename CharT>
  129. struct escape_char_action_parser_gen {
  130. template <typename ParserT, typename ActionT>
  131. static escape_char_action<ParserT, ActionT, Flags, CharT>
  132. generate (ParserT const &p, ActionT const &actor)
  133. {
  134. typedef
  135. escape_char_action<ParserT, ActionT, Flags, CharT>
  136. action_parser_t;
  137. return action_parser_t(p, actor);
  138. }
  139. };
  140. ///////////////////////////////////////////////////////////////////////////////
  141. //
  142. // predefined escape_char_parser objects
  143. //
  144. // These objects should be used for generating correct escaped character
  145. // parsers.
  146. //
  147. ///////////////////////////////////////////////////////////////////////////////
  148. const escape_char_parser<lex_escapes> lex_escape_ch_p =
  149. escape_char_parser<lex_escapes>();
  150. const escape_char_parser<c_escapes> c_escape_ch_p =
  151. escape_char_parser<c_escapes>();
  152. ///////////////////////////////////////////////////////////////////////////////
  153. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  154. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  155. #endif