annotate DEPENDENCIES/generic/include/boost/wave/grammars/cpp_chlit_grammar.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Boost.Wave: A Standard compliant C++ preprocessor library
Chris@16 3
Chris@16 4 http://www.boost.org/
Chris@16 5
Chris@16 6 Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
Chris@16 7 Software License, Version 1.0. (See accompanying file
Chris@16 8 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 =============================================================================*/
Chris@16 10
Chris@16 11 #if !defined(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)
Chris@16 12 #define CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED
Chris@16 13
Chris@16 14 #include <limits> // std::numeric_limits
Chris@16 15 #include <climits> // CHAR_BIT
Chris@16 16
Chris@16 17 #include <boost/wave/wave_config.hpp>
Chris@16 18
Chris@16 19 #include <boost/static_assert.hpp>
Chris@16 20 #include <boost/cstdint.hpp>
Chris@16 21
Chris@16 22 #include <boost/spirit/include/classic_core.hpp>
Chris@16 23 #include <boost/spirit/include/classic_closure.hpp>
Chris@16 24 #include <boost/spirit/include/classic_if.hpp>
Chris@16 25 #include <boost/spirit/include/classic_assign_actor.hpp>
Chris@16 26 #include <boost/spirit/include/classic_push_back_actor.hpp>
Chris@16 27
Chris@16 28 #include <boost/spirit/include/phoenix1_operators.hpp>
Chris@16 29 #include <boost/spirit/include/phoenix1_primitives.hpp>
Chris@16 30 #include <boost/spirit/include/phoenix1_statements.hpp>
Chris@16 31 #include <boost/spirit/include/phoenix1_functions.hpp>
Chris@16 32
Chris@16 33 #include <boost/wave/cpp_exceptions.hpp>
Chris@16 34 #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
Chris@16 35
Chris@16 36 #if !defined(spirit_append_actor)
Chris@16 37 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
Chris@16 38 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
Chris@16 39 #endif // !defined(spirit_append_actor)
Chris@16 40
Chris@16 41 // this must occur after all of the includes and before any code appears
Chris@16 42 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 43 #include BOOST_ABI_PREFIX
Chris@16 44 #endif
Chris@16 45
Chris@16 46 ///////////////////////////////////////////////////////////////////////////////
Chris@16 47 //
Chris@16 48 // Reusable grammar to parse a C++ style character literal
Chris@16 49 //
Chris@16 50 ///////////////////////////////////////////////////////////////////////////////
Chris@16 51 namespace boost {
Chris@16 52 namespace wave {
Chris@16 53 namespace grammars {
Chris@16 54
Chris@16 55 namespace closures {
Chris@16 56
Chris@16 57 struct chlit_closure
Chris@16 58 : boost::spirit::classic::closure<chlit_closure, boost::uint32_t, bool>
Chris@16 59 {
Chris@16 60 member1 value;
Chris@16 61 member2 long_lit;
Chris@16 62 };
Chris@16 63 }
Chris@16 64
Chris@16 65 namespace impl {
Chris@16 66
Chris@16 67 ///////////////////////////////////////////////////////////////////////////////
Chris@16 68 //
Chris@16 69 // compose a multibyte character literal
Chris@16 70 //
Chris@16 71 ///////////////////////////////////////////////////////////////////////////////
Chris@16 72 struct compose_character_literal {
Chris@16 73
Chris@16 74 template <typename A1, typename A2, typename A3, typename A4>
Chris@16 75 struct result
Chris@16 76 {
Chris@16 77 typedef void type;
Chris@16 78 };
Chris@16 79
Chris@16 80 void
Chris@16 81 operator()(boost::uint32_t& value, bool long_lit, bool& overflow,
Chris@16 82 boost::uint32_t character) const
Chris@16 83 {
Chris@16 84 // The following assumes that wchar_t is max. 32 Bit
Chris@16 85 BOOST_STATIC_ASSERT(sizeof(wchar_t) <= 4);
Chris@16 86
Chris@16 87 static boost::uint32_t masks[] = {
Chris@16 88 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
Chris@16 89 };
Chris@16 90 static boost::uint32_t overflow_masks[] = {
Chris@16 91 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff
Chris@16 92 };
Chris@16 93
Chris@16 94 if (long_lit) {
Chris@16 95 // make sure no overflow will occur below
Chris@16 96 if ((value & overflow_masks[sizeof(wchar_t)-1]) != 0) {
Chris@16 97 overflow |= true;
Chris@16 98 }
Chris@16 99 else {
Chris@16 100 // calculate the new value (avoiding a warning regarding
Chris@16 101 // shifting count >= size of the type)
Chris@16 102 value <<= CHAR_BIT * (sizeof(wchar_t)-1);
Chris@16 103 value <<= CHAR_BIT;
Chris@16 104 value |= character & masks[sizeof(wchar_t)-1];
Chris@16 105 }
Chris@16 106 }
Chris@16 107 else {
Chris@16 108 // make sure no overflow will occur below
Chris@16 109 if ((value & overflow_masks[sizeof(char)-1]) != 0) {
Chris@16 110 overflow |= true;
Chris@16 111 }
Chris@16 112 else {
Chris@16 113 // calculate the new value
Chris@16 114 value <<= CHAR_BIT * sizeof(char);
Chris@16 115 value |= character & masks[sizeof(char)-1];
Chris@16 116 }
Chris@16 117 }
Chris@16 118 }
Chris@16 119 };
Chris@16 120 phoenix::function<compose_character_literal> const compose;
Chris@16 121
Chris@16 122 } // namespace impl
Chris@16 123
Chris@16 124 ///////////////////////////////////////////////////////////////////////////////
Chris@16 125 // define, whether the rule's should generate some debug output
Chris@16 126 #define TRACE_CHLIT_GRAMMAR \
Chris@16 127 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR) \
Chris@16 128 /**/
Chris@16 129
Chris@16 130 struct chlit_grammar :
Chris@16 131 public boost::spirit::classic::grammar<chlit_grammar,
Chris@16 132 closures::chlit_closure::context_t>
Chris@16 133 {
Chris@16 134 chlit_grammar()
Chris@16 135 : overflow(false)
Chris@16 136 {
Chris@16 137 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "chlit_grammar",
Chris@16 138 TRACE_CHLIT_GRAMMAR);
Chris@16 139 }
Chris@16 140
Chris@16 141 // no need for copy constructor/assignment operator
Chris@16 142 chlit_grammar(chlit_grammar const&);
Chris@16 143 chlit_grammar& operator=(chlit_grammar const&);
Chris@16 144
Chris@16 145 template <typename ScannerT>
Chris@16 146 struct definition
Chris@16 147 {
Chris@16 148 typedef boost::spirit::classic::rule<
Chris@16 149 ScannerT, closures::chlit_closure::context_t>
Chris@16 150 rule_t;
Chris@16 151
Chris@16 152 rule_t ch_lit;
Chris@16 153
Chris@16 154 definition(chlit_grammar const &self)
Chris@16 155 {
Chris@16 156 using namespace boost::spirit::classic;
Chris@16 157 namespace phx = phoenix;
Chris@16 158
Chris@16 159 // special parsers for '\x..' and L'\x....'
Chris@16 160 typedef uint_parser<
Chris@16 161 unsigned int, 16, 1, 2 * sizeof(char)
Chris@16 162 > hex_char_parser_type;
Chris@16 163 typedef uint_parser<
Chris@16 164 unsigned int, 16, 1, 2 * sizeof(wchar_t)
Chris@16 165 > hex_wchar_parser_type;
Chris@16 166
Chris@16 167 // the rule for a character literal
Chris@16 168 ch_lit
Chris@16 169 = eps_p[self.value = phx::val(0), self.long_lit = phx::val(false)]
Chris@16 170 >> !ch_p('L')[self.long_lit = phx::val(true)]
Chris@16 171 >> ch_p('\'')
Chris@16 172 >> +( (
Chris@16 173 ch_p('\\')
Chris@16 174 >> ( ch_p('a') // BEL
Chris@16 175 [
Chris@16 176 impl::compose(self.value, self.long_lit,
Chris@16 177 phx::var(self.overflow), phx::val(0x07))
Chris@16 178 ]
Chris@16 179 | ch_p('b') // BS
Chris@16 180 [
Chris@16 181 impl::compose(self.value, self.long_lit,
Chris@16 182 phx::var(self.overflow), phx::val(0x08))
Chris@16 183 ]
Chris@16 184 | ch_p('t') // HT
Chris@16 185 [
Chris@16 186 impl::compose(self.value, self.long_lit,
Chris@16 187 phx::var(self.overflow), phx::val(0x09))
Chris@16 188 ]
Chris@16 189 | ch_p('n') // NL
Chris@16 190 [
Chris@16 191 impl::compose(self.value, self.long_lit,
Chris@16 192 phx::var(self.overflow), phx::val(0x0a))
Chris@16 193 ]
Chris@16 194 | ch_p('v') // VT
Chris@16 195 [
Chris@16 196 impl::compose(self.value, self.long_lit,
Chris@16 197 phx::var(self.overflow), phx::val(0x0b))
Chris@16 198 ]
Chris@16 199 | ch_p('f') // FF
Chris@16 200 [
Chris@16 201 impl::compose(self.value, self.long_lit,
Chris@16 202 phx::var(self.overflow), phx::val(0x0c))
Chris@16 203 ]
Chris@16 204 | ch_p('r') // CR
Chris@16 205 [
Chris@16 206 impl::compose(self.value, self.long_lit,
Chris@16 207 phx::var(self.overflow), phx::val(0x0d))
Chris@16 208 ]
Chris@16 209 | ch_p('?')
Chris@16 210 [
Chris@16 211 impl::compose(self.value, self.long_lit,
Chris@16 212 phx::var(self.overflow), phx::val('?'))
Chris@16 213 ]
Chris@16 214 | ch_p('\'')
Chris@16 215 [
Chris@16 216 impl::compose(self.value, self.long_lit,
Chris@16 217 phx::var(self.overflow), phx::val('\''))
Chris@16 218 ]
Chris@16 219 | ch_p('\"')
Chris@16 220 [
Chris@16 221 impl::compose(self.value, self.long_lit,
Chris@16 222 phx::var(self.overflow), phx::val('\"'))
Chris@16 223 ]
Chris@16 224 | ch_p('\\')
Chris@16 225 [
Chris@16 226 impl::compose(self.value, self.long_lit,
Chris@16 227 phx::var(self.overflow), phx::val('\\'))
Chris@16 228 ]
Chris@16 229 | ch_p('x')
Chris@16 230 >> if_p(self.long_lit)
Chris@16 231 [
Chris@16 232 hex_wchar_parser_type()
Chris@16 233 [
Chris@16 234 impl::compose(self.value, self.long_lit,
Chris@16 235 phx::var(self.overflow), phx::arg1)
Chris@16 236 ]
Chris@16 237 ]
Chris@16 238 .else_p
Chris@16 239 [
Chris@16 240 hex_char_parser_type()
Chris@16 241 [
Chris@16 242 impl::compose(self.value, self.long_lit,
Chris@16 243 phx::var(self.overflow), phx::arg1)
Chris@16 244 ]
Chris@16 245 ]
Chris@16 246 | ch_p('u')
Chris@16 247 >> uint_parser<unsigned int, 16, 4, 4>()
Chris@16 248 [
Chris@16 249 impl::compose(self.value, self.long_lit,
Chris@16 250 phx::var(self.overflow), phx::arg1)
Chris@16 251 ]
Chris@16 252 | ch_p('U')
Chris@16 253 >> uint_parser<unsigned int, 16, 8, 8>()
Chris@16 254 [
Chris@16 255 impl::compose(self.value, self.long_lit,
Chris@16 256 phx::var(self.overflow), phx::arg1)
Chris@16 257 ]
Chris@16 258 | uint_parser<unsigned int, 8, 1, 3>()
Chris@16 259 [
Chris@16 260 impl::compose(self.value, self.long_lit,
Chris@16 261 phx::var(self.overflow), phx::arg1)
Chris@16 262 ]
Chris@16 263 )
Chris@16 264 )
Chris@16 265 | ~eps_p(ch_p('\'')) >> anychar_p
Chris@16 266 [
Chris@16 267 impl::compose(self.value, self.long_lit,
Chris@16 268 phx::var(self.overflow), phx::arg1)
Chris@16 269 ]
Chris@16 270 )
Chris@16 271 >> ch_p('\'')
Chris@16 272 ;
Chris@16 273
Chris@16 274 BOOST_SPIRIT_DEBUG_TRACE_RULE(ch_lit, TRACE_CHLIT_GRAMMAR);
Chris@16 275 }
Chris@16 276
Chris@16 277 // start rule of this grammar
Chris@16 278 rule_t const& start() const
Chris@16 279 { return ch_lit; }
Chris@16 280 };
Chris@16 281
Chris@16 282 // flag signaling integer overflow during value composition
Chris@16 283 mutable bool overflow;
Chris@16 284 };
Chris@16 285
Chris@16 286 #undef TRACE_CHLIT_GRAMMAR
Chris@16 287
Chris@16 288 ///////////////////////////////////////////////////////////////////////////////
Chris@16 289 //
Chris@16 290 // The following function is defined here, to allow the separation of
Chris@16 291 // the compilation of the intlit_grammap from the function using it.
Chris@16 292 //
Chris@16 293 ///////////////////////////////////////////////////////////////////////////////
Chris@16 294
Chris@16 295 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
Chris@16 296 #define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
Chris@16 297 #else
Chris@16 298 #define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE inline
Chris@16 299 #endif
Chris@16 300
Chris@16 301 template <typename IntegralResult, typename TokenT>
Chris@16 302 BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
Chris@16 303 IntegralResult
Chris@16 304 chlit_grammar_gen<IntegralResult, TokenT>::evaluate(TokenT const &token, value_error &status)
Chris@16 305 {
Chris@16 306 using namespace boost::spirit::classic;
Chris@16 307
Chris@16 308 chlit_grammar g;
Chris@16 309 IntegralResult result = 0;
Chris@16 310 typename TokenT::string_type const &token_val = token.get_value();
Chris@16 311 parse_info<typename TokenT::string_type::const_iterator> hit =
Chris@16 312 parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
Chris@16 313
Chris@16 314 if (!hit.hit) {
Chris@16 315 BOOST_WAVE_THROW(preprocess_exception, ill_formed_character_literal,
Chris@16 316 token_val.c_str(), token.get_position());
Chris@16 317 }
Chris@16 318 else {
Chris@16 319 // range check
Chris@16 320 if ('L' == token_val[0]) {
Chris@16 321 // recognized wide character
Chris@16 322 if (g.overflow ||
Chris@16 323 result > (IntegralResult)(std::numeric_limits<wchar_t>::max)())
Chris@16 324 {
Chris@16 325 // out of range
Chris@16 326 status = error_character_overflow;
Chris@16 327 }
Chris@16 328 }
Chris@16 329 else {
Chris@16 330 // recognized narrow ('normal') character
Chris@16 331 if (g.overflow ||
Chris@16 332 result > (IntegralResult)(std::numeric_limits<unsigned char>::max)())
Chris@16 333 {
Chris@16 334 // out of range
Chris@16 335 status = error_character_overflow;
Chris@16 336 }
Chris@16 337 }
Chris@16 338 }
Chris@16 339 return result;
Chris@16 340 }
Chris@16 341
Chris@16 342 #undef BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
Chris@16 343
Chris@16 344 ///////////////////////////////////////////////////////////////////////////////
Chris@16 345 } // namespace grammars
Chris@16 346 } // namespace wave
Chris@16 347 } // namespace boost
Chris@16 348
Chris@16 349 // the suffix header occurs after all of the code
Chris@16 350 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 351 #include BOOST_ABI_SUFFIX
Chris@16 352 #endif
Chris@16 353
Chris@16 354 #endif // !defined(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)