Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:39

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     http://www.boost.org/
0005 
0006     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0007     Software License, Version 1.0. (See accompanying file
0008     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 =============================================================================*/
0010 
0011 #if !defined(BOOST_CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)
0012 #define BOOST_CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED
0013 
0014 #include <limits>     // std::numeric_limits
0015 #include <climits>    // CHAR_BIT
0016 
0017 #include <boost/wave/wave_config.hpp>
0018 
0019 #include <boost/static_assert.hpp>
0020 #include <boost/cstdint.hpp>
0021 
0022 #include <boost/spirit/include/classic_core.hpp>
0023 #include <boost/spirit/include/classic_closure.hpp>
0024 #include <boost/spirit/include/classic_if.hpp>
0025 #include <boost/spirit/include/classic_assign_actor.hpp>
0026 #include <boost/spirit/include/classic_push_back_actor.hpp>
0027 
0028 #include <boost/spirit/include/phoenix1_operators.hpp>
0029 #include <boost/spirit/include/phoenix1_primitives.hpp>
0030 #include <boost/spirit/include/phoenix1_statements.hpp>
0031 #include <boost/spirit/include/phoenix1_functions.hpp>
0032 
0033 #include <boost/wave/cpp_exceptions.hpp>
0034 #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
0035 
0036 #if !defined(spirit_append_actor)
0037 #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
0038 #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
0039 #endif // !defined(spirit_append_actor)
0040 
0041 // this must occur after all of the includes and before any code appears
0042 #ifdef BOOST_HAS_ABI_HEADERS
0043 #include BOOST_ABI_PREFIX
0044 #endif
0045 
0046 ///////////////////////////////////////////////////////////////////////////////
0047 //
0048 //  Reusable grammar to parse a C++ style character literal
0049 //
0050 ///////////////////////////////////////////////////////////////////////////////
0051 namespace boost {
0052 namespace wave {
0053 namespace grammars {
0054 
0055 namespace closures {
0056 
0057     struct chlit_closure
0058     :   boost::spirit::classic::closure<chlit_closure, boost::uint32_t, bool>
0059     {
0060         member1 value;
0061         member2 long_lit;
0062     };
0063 }
0064 
0065 namespace impl {
0066 
0067 ///////////////////////////////////////////////////////////////////////////////
0068 //
0069 //  compose a multibyte character literal
0070 //
0071 ///////////////////////////////////////////////////////////////////////////////
0072     struct compose_character_literal {
0073 
0074         template <typename A1, typename A2, typename A3, typename A4>
0075         struct result
0076         {
0077             typedef void type;
0078         };
0079 
0080         void
0081         operator()(boost::uint32_t& value, bool long_lit, bool& overflow,
0082             boost::uint32_t character) const
0083         {
0084             // The following assumes that wchar_t is max. 32 Bit
0085             BOOST_STATIC_ASSERT(sizeof(wchar_t) <= 4);
0086 
0087             static boost::uint32_t masks[] = {
0088                 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
0089             };
0090             static boost::uint32_t overflow_masks[] = {
0091                 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff
0092             };
0093 
0094             if (long_lit) {
0095             // make sure no overflow will occur below
0096                 if ((value & overflow_masks[sizeof(wchar_t)-1]) != 0) {
0097                     overflow |= true;
0098                 }
0099                 else {
0100                 // calculate the new value (avoiding a warning regarding
0101                 // shifting count >= size of the type)
0102                     value <<= CHAR_BIT * (sizeof(wchar_t)-1);
0103                     value <<= CHAR_BIT;
0104                     value |= character & masks[sizeof(wchar_t)-1];
0105                 }
0106             }
0107             else {
0108             // make sure no overflow will occur below
0109                 if ((value & overflow_masks[sizeof(char)-1]) != 0) {
0110                     overflow |= true;
0111                 }
0112                 else {
0113                 // calculate the new value
0114                     value <<= CHAR_BIT * sizeof(char);
0115                     value |= character & masks[sizeof(char)-1];
0116                 }
0117             }
0118         }
0119     };
0120     phoenix::function<compose_character_literal> const compose;
0121 
0122 }   // namespace impl
0123 
0124 ///////////////////////////////////////////////////////////////////////////////
0125 //  define, whether the rule's should generate some debug output
0126 #define TRACE_CHLIT_GRAMMAR \
0127     bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR) \
0128     /**/
0129 
0130 struct chlit_grammar :
0131     public boost::spirit::classic::grammar<chlit_grammar,
0132         closures::chlit_closure::context_t>
0133 {
0134     chlit_grammar()
0135     :   overflow(false)
0136     {
0137         BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "chlit_grammar",
0138             TRACE_CHLIT_GRAMMAR);
0139     }
0140 
0141     // no need for copy constructor/assignment operator
0142     chlit_grammar(chlit_grammar const&);
0143     chlit_grammar& operator=(chlit_grammar const&);
0144 
0145     template <typename ScannerT>
0146     struct definition
0147     {
0148         typedef boost::spirit::classic::rule<
0149                 ScannerT, closures::chlit_closure::context_t>
0150             rule_t;
0151 
0152         rule_t ch_lit;
0153 
0154         definition(chlit_grammar const &self)
0155         {
0156             using namespace boost::spirit::classic;
0157             namespace phx = phoenix;
0158 
0159             // special parsers for '\x..' and L'\x....'
0160             typedef uint_parser<
0161                         unsigned int, 16, 1, 2 * sizeof(char)
0162                     > hex_char_parser_type;
0163             typedef uint_parser<
0164                         unsigned int, 16, 1, 2 * sizeof(wchar_t)
0165                     > hex_wchar_parser_type;
0166 
0167             // the rule for a character literal
0168             ch_lit
0169                 =   eps_p[(self.value = phx::val(0), self.long_lit = phx::val(false))]
0170                     >> !ch_p('L')[self.long_lit = phx::val(true)]
0171                     >>  ch_p('\'')
0172                     >> +(   (
0173                             ch_p('\\')
0174                             >>  (   ch_p('a')    // BEL
0175                                     [
0176                                         impl::compose(self.value, self.long_lit,
0177                                             phx::var(self.overflow), phx::val(0x07))
0178                                     ]
0179                                 |   ch_p('b')    // BS
0180                                     [
0181                                         impl::compose(self.value, self.long_lit,
0182                                             phx::var(self.overflow), phx::val(0x08))
0183                                     ]
0184                                 |   ch_p('t')    // HT
0185                                     [
0186                                         impl::compose(self.value, self.long_lit,
0187                                             phx::var(self.overflow), phx::val(0x09))
0188                                     ]
0189                                 |   ch_p('n')    // NL
0190                                     [
0191                                         impl::compose(self.value, self.long_lit,
0192                                             phx::var(self.overflow), phx::val(0x0a))
0193                                     ]
0194                                 |   ch_p('v')    // VT
0195                                     [
0196                                         impl::compose(self.value, self.long_lit,
0197                                             phx::var(self.overflow), phx::val(0x0b))
0198                                     ]
0199                                 |   (ch_p('e') | ch_p('E'))   // ESC
0200                                     [
0201                                         impl::compose(self.value, self.long_lit,
0202                                             phx::var(self.overflow), phx::val(0x1b))
0203                                     ]
0204                                 |   ch_p('f')    // FF
0205                                     [
0206                                         impl::compose(self.value, self.long_lit,
0207                                             phx::var(self.overflow), phx::val(0x0c))
0208                                     ]
0209                                 |   ch_p('r')    // CR
0210                                     [
0211                                         impl::compose(self.value, self.long_lit,
0212                                             phx::var(self.overflow), phx::val(0x0d))
0213                                     ]
0214                                 |   ch_p('?')
0215                                     [
0216                                         impl::compose(self.value, self.long_lit,
0217                                             phx::var(self.overflow), phx::val('?'))
0218                                     ]
0219                                 |   ch_p('\'')
0220                                     [
0221                                         impl::compose(self.value, self.long_lit,
0222                                             phx::var(self.overflow), phx::val('\''))
0223                                     ]
0224                                 |   ch_p('\"')
0225                                     [
0226                                         impl::compose(self.value, self.long_lit,
0227                                             phx::var(self.overflow), phx::val('\"'))
0228                                     ]
0229                                 |   ch_p('\\')
0230                                     [
0231                                         impl::compose(self.value, self.long_lit,
0232                                             phx::var(self.overflow), phx::val('\\'))
0233                                     ]
0234                                 |   ch_p('x')
0235                                     >>  if_p(self.long_lit)
0236                                         [
0237                                             hex_wchar_parser_type()
0238                                             [
0239                                                 impl::compose(self.value, self.long_lit,
0240                                                     phx::var(self.overflow), phx::arg1)
0241                                             ]
0242                                         ]
0243                                         .else_p
0244                                         [
0245                                             hex_char_parser_type()
0246                                             [
0247                                                 impl::compose(self.value, self.long_lit,
0248                                                     phx::var(self.overflow), phx::arg1)
0249                                             ]
0250                                         ]
0251                                 |   ch_p('u')
0252                                     >>  uint_parser<unsigned int, 16, 4, 4>()
0253                                         [
0254                                             impl::compose(self.value, self.long_lit,
0255                                                 phx::var(self.overflow), phx::arg1)
0256                                         ]
0257                                 |   ch_p('U')
0258                                     >>  uint_parser<unsigned int, 16, 8, 8>()
0259                                         [
0260                                             impl::compose(self.value, self.long_lit,
0261                                                 phx::var(self.overflow), phx::arg1)
0262                                         ]
0263                                 |   uint_parser<unsigned int, 8, 1, 3>()
0264                                     [
0265                                         impl::compose(self.value, self.long_lit,
0266                                             phx::var(self.overflow), phx::arg1)
0267                                     ]
0268                                 )
0269                             )
0270                         |   ~eps_p(ch_p('\'')) >> anychar_p
0271                             [
0272                                 impl::compose(self.value, self.long_lit,
0273                                     phx::var(self.overflow), phx::arg1)
0274                             ]
0275                         )
0276                     >>  ch_p('\'')
0277                 ;
0278 
0279             BOOST_SPIRIT_DEBUG_TRACE_RULE(ch_lit, TRACE_CHLIT_GRAMMAR);
0280         }
0281 
0282         // start rule of this grammar
0283         rule_t const& start() const
0284         { return ch_lit; }
0285     };
0286 
0287     // flag signaling integer overflow during value composition
0288     mutable bool overflow;
0289 };
0290 
0291 #undef TRACE_CHLIT_GRAMMAR
0292 
0293 ///////////////////////////////////////////////////////////////////////////////
0294 //
0295 //  The following function is defined here, to allow the separation of
0296 //  the compilation of the intlit_grammap from the function using it.
0297 //
0298 ///////////////////////////////////////////////////////////////////////////////
0299 
0300 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
0301 #define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
0302 #else
0303 #define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE inline
0304 #endif
0305 
0306 template <typename IntegralResult, typename TokenT>
0307 BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
0308 IntegralResult
0309 chlit_grammar_gen<IntegralResult, TokenT>::evaluate(TokenT const &token, value_error &status)
0310 {
0311     using namespace boost::spirit::classic;
0312 
0313 chlit_grammar g;
0314 IntegralResult result = 0;
0315 typename TokenT::string_type const &token_val = token.get_value();
0316 parse_info<typename TokenT::string_type::const_iterator> hit =
0317     parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
0318 
0319     if (!hit.hit) {
0320         BOOST_WAVE_THROW(preprocess_exception, ill_formed_character_literal,
0321             token_val.c_str(), token.get_position());
0322     }
0323     else {
0324         // range check
0325         if ('L' == token_val[0]) {
0326             // recognized wide character
0327             if (g.overflow ||
0328                 result > (IntegralResult)(std::numeric_limits<wchar_t>::max)())
0329             {
0330                 // out of range
0331                 status = error_character_overflow;
0332             }
0333         }
0334         else {
0335             // recognized narrow ('normal') character
0336             if (g.overflow ||
0337                 result > (IntegralResult)(std::numeric_limits<unsigned char>::max)())
0338             {
0339                 // out of range
0340                 status = error_character_overflow;
0341             }
0342         }
0343     }
0344     return result;
0345 }
0346 
0347 #undef BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
0348 
0349 ///////////////////////////////////////////////////////////////////////////////
0350 }   // namespace grammars
0351 }   // namespace wave
0352 }   // namespace boost
0353 
0354 // the suffix header occurs after all of the code
0355 #ifdef BOOST_HAS_ABI_HEADERS
0356 #include BOOST_ABI_SUFFIX
0357 #endif
0358 
0359 #endif // !defined(BOOST_CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)