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