File indexing completed on 2025-01-18 09:53:39
0001
0002
0003
0004
0005
0006
0007
0008
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
0040
0041
0042 #ifdef BOOST_HAS_ABI_HEADERS
0043 #include BOOST_ABI_PREFIX
0044 #endif
0045
0046
0047
0048
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
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
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
0096 if ((value & overflow_masks[sizeof(wchar_t)-1]) != 0) {
0097 overflow |= true;
0098 }
0099 else {
0100
0101
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
0109 if ((value & overflow_masks[sizeof(char)-1]) != 0) {
0110 overflow |= true;
0111 }
0112 else {
0113
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 }
0123
0124
0125
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
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
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
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')
0175 [
0176 impl::compose(self.value, self.long_lit,
0177 phx::var(self.overflow), phx::val(0x07))
0178 ]
0179 | ch_p('b')
0180 [
0181 impl::compose(self.value, self.long_lit,
0182 phx::var(self.overflow), phx::val(0x08))
0183 ]
0184 | ch_p('t')
0185 [
0186 impl::compose(self.value, self.long_lit,
0187 phx::var(self.overflow), phx::val(0x09))
0188 ]
0189 | ch_p('n')
0190 [
0191 impl::compose(self.value, self.long_lit,
0192 phx::var(self.overflow), phx::val(0x0a))
0193 ]
0194 | ch_p('v')
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'))
0200 [
0201 impl::compose(self.value, self.long_lit,
0202 phx::var(self.overflow), phx::val(0x1b))
0203 ]
0204 | ch_p('f')
0205 [
0206 impl::compose(self.value, self.long_lit,
0207 phx::var(self.overflow), phx::val(0x0c))
0208 ]
0209 | ch_p('r')
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
0283 rule_t const& start() const
0284 { return ch_lit; }
0285 };
0286
0287
0288 mutable bool overflow;
0289 };
0290
0291 #undef TRACE_CHLIT_GRAMMAR
0292
0293
0294
0295
0296
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
0325 if ('L' == token_val[0]) {
0326
0327 if (g.overflow ||
0328 result > (IntegralResult)(std::numeric_limits<wchar_t>::max)())
0329 {
0330
0331 status = error_character_overflow;
0332 }
0333 }
0334 else {
0335
0336 if (g.overflow ||
0337 result > (IntegralResult)(std::numeric_limits<unsigned char>::max)())
0338 {
0339
0340 status = error_character_overflow;
0341 }
0342 }
0343 }
0344 return result;
0345 }
0346
0347 #undef BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
0348
0349
0350 }
0351 }
0352 }
0353
0354
0355 #ifdef BOOST_HAS_ABI_HEADERS
0356 #include BOOST_ABI_SUFFIX
0357 #endif
0358
0359 #endif