cpp_intlit_grammar.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. http://www.boost.org/
  4. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  5. Software License, Version 1.0. (See accompanying file
  6. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)
  9. #define BOOST_CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED
  10. #include <boost/wave/wave_config.hpp>
  11. #include <boost/spirit/include/classic_core.hpp>
  12. #include <boost/spirit/include/classic_closure.hpp>
  13. #include <boost/spirit/include/classic_assign_actor.hpp>
  14. #include <boost/spirit/include/classic_push_back_actor.hpp>
  15. #include <boost/spirit/include/phoenix1_operators.hpp>
  16. #include <boost/spirit/include/phoenix1_primitives.hpp>
  17. #include <boost/spirit/include/phoenix1_statements.hpp>
  18. #include <boost/wave/cpp_exceptions.hpp>
  19. #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
  20. #if !defined(spirit_append_actor)
  21. #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
  22. #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
  23. #endif // !defined(spirit_append_actor)
  24. // this must occur after all of the includes and before any code appears
  25. #ifdef BOOST_HAS_ABI_HEADERS
  26. #include BOOST_ABI_PREFIX
  27. #endif
  28. ///////////////////////////////////////////////////////////////////////////////
  29. //
  30. // Reusable grammar for parsing of C++ style integer literals
  31. //
  32. ///////////////////////////////////////////////////////////////////////////////
  33. namespace boost {
  34. namespace wave {
  35. namespace grammars {
  36. ///////////////////////////////////////////////////////////////////////////////
  37. namespace closures {
  38. struct intlit_closure
  39. : boost::spirit::classic::closure<intlit_closure, uint_literal_type>
  40. {
  41. member1 val;
  42. };
  43. }
  44. ///////////////////////////////////////////////////////////////////////////////
  45. // define, whether the rule's should generate some debug output
  46. #define TRACE_INTLIT_GRAMMAR \
  47. bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR) \
  48. /**/
  49. struct intlit_grammar :
  50. boost::spirit::classic::grammar<intlit_grammar, closures::intlit_closure::context_t>
  51. {
  52. intlit_grammar(bool &is_unsigned_) : is_unsigned(is_unsigned_)
  53. {
  54. BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "intlit_grammar",
  55. TRACE_INTLIT_GRAMMAR);
  56. }
  57. template <typename ScannerT>
  58. struct definition
  59. {
  60. typedef boost::spirit::classic::rule<ScannerT> rule_t;
  61. rule_t int_lit;
  62. boost::spirit::classic::subrule<0> sub_int_lit;
  63. boost::spirit::classic::subrule<1> oct_lit;
  64. boost::spirit::classic::subrule<2> hex_lit;
  65. boost::spirit::classic::subrule<3> dec_lit;
  66. definition(intlit_grammar const &self)
  67. {
  68. using namespace boost::spirit::classic;
  69. namespace phx = phoenix;
  70. int_lit = (
  71. sub_int_lit =
  72. ( ch_p('0')[self.val = 0] >> (hex_lit | oct_lit)
  73. | dec_lit
  74. )
  75. >> !as_lower_d[
  76. (ch_p('u')[phx::var(self.is_unsigned) = true] || ch_p('l'))
  77. | (ch_p('l') || ch_p('u')[phx::var(self.is_unsigned) = true])
  78. ]
  79. ,
  80. hex_lit =
  81. (ch_p('X') | ch_p('x'))
  82. >> uint_parser<uint_literal_type, 16>()
  83. [
  84. self.val = phx::arg1,
  85. phx::var(self.is_unsigned) = true
  86. ]
  87. ,
  88. oct_lit =
  89. !uint_parser<uint_literal_type, 8>()
  90. [
  91. self.val = phx::arg1,
  92. phx::var(self.is_unsigned) = true
  93. ]
  94. ,
  95. dec_lit =
  96. uint_parser<uint_literal_type, 10>()
  97. [
  98. self.val = phx::arg1
  99. ]
  100. )
  101. ;
  102. BOOST_SPIRIT_DEBUG_TRACE_RULE(int_lit, TRACE_INTLIT_GRAMMAR);
  103. BOOST_SPIRIT_DEBUG_TRACE_RULE(sub_int_lit, TRACE_INTLIT_GRAMMAR);
  104. BOOST_SPIRIT_DEBUG_TRACE_RULE(hex_lit, TRACE_INTLIT_GRAMMAR);
  105. BOOST_SPIRIT_DEBUG_TRACE_RULE(oct_lit, TRACE_INTLIT_GRAMMAR);
  106. BOOST_SPIRIT_DEBUG_TRACE_RULE(dec_lit, TRACE_INTLIT_GRAMMAR);
  107. }
  108. // start rule of this grammar
  109. rule_t const& start() const
  110. { return int_lit; }
  111. };
  112. bool &is_unsigned;
  113. };
  114. #undef TRACE_INTLIT_GRAMMAR
  115. ///////////////////////////////////////////////////////////////////////////////
  116. //
  117. // The following function is defined here, to allow the separation of
  118. // the compilation of the intlit_grammar from the function using it.
  119. //
  120. ///////////////////////////////////////////////////////////////////////////////
  121. #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
  122. #define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
  123. #else
  124. #define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE inline
  125. #endif
  126. template <typename TokenT>
  127. BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
  128. uint_literal_type
  129. intlit_grammar_gen<TokenT>::evaluate(TokenT const &token,
  130. bool &is_unsigned)
  131. {
  132. intlit_grammar g(is_unsigned);
  133. uint_literal_type result = 0;
  134. typename TokenT::string_type const &token_val = token.get_value();
  135. using boost::spirit::classic::parse_info;
  136. parse_info<typename TokenT::string_type::const_iterator> hit =
  137. parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
  138. if (!hit.hit) {
  139. BOOST_WAVE_THROW(preprocess_exception, ill_formed_integer_literal,
  140. token_val.c_str(), token.get_position());
  141. }
  142. return result;
  143. }
  144. #undef BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
  145. ///////////////////////////////////////////////////////////////////////////////
  146. } // namespace grammars
  147. } // namespace wave
  148. } // namespace boost
  149. // the suffix header occurs after all of the code
  150. #ifdef BOOST_HAS_ABI_HEADERS
  151. #include BOOST_ABI_SUFFIX
  152. #endif
  153. #endif // !defined(BOOST_CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)