Chris@16: /*============================================================================= Chris@16: Boost.Wave: A Standard compliant C++ preprocessor library Chris@16: Chris@16: http://www.boost.org/ Chris@16: Chris@16: Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost Chris@16: Software License, Version 1.0. (See accompanying file Chris@16: LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: Chris@16: #if !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED) Chris@16: #define CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if !defined(spirit_append_actor) Chris@16: #define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor) Chris@16: #define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor) Chris@16: #endif // !defined(spirit_append_actor) Chris@16: Chris@16: // this must occur after all of the includes and before any code appears Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // Reusable grammar for parsing of C++ style integer literals Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { Chris@16: namespace wave { Chris@16: namespace grammars { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace closures { Chris@16: Chris@16: struct intlit_closure Chris@16: : boost::spirit::classic::closure Chris@16: { Chris@16: member1 val; Chris@16: }; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // define, whether the rule's should generate some debug output Chris@16: #define TRACE_INTLIT_GRAMMAR \ Chris@16: bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR) \ Chris@16: /**/ Chris@16: Chris@16: struct intlit_grammar : Chris@16: boost::spirit::classic::grammar Chris@16: { Chris@16: intlit_grammar(bool &is_unsigned_) : is_unsigned(is_unsigned_) Chris@16: { Chris@16: BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "intlit_grammar", Chris@16: TRACE_INTLIT_GRAMMAR); Chris@16: } Chris@16: Chris@16: template Chris@16: struct definition Chris@16: { Chris@16: typedef boost::spirit::classic::rule rule_t; Chris@16: Chris@16: rule_t int_lit; Chris@16: boost::spirit::classic::subrule<0> sub_int_lit; Chris@16: boost::spirit::classic::subrule<1> oct_lit; Chris@16: boost::spirit::classic::subrule<2> hex_lit; Chris@16: boost::spirit::classic::subrule<3> dec_lit; Chris@16: Chris@16: definition(intlit_grammar const &self) Chris@16: { Chris@16: using namespace boost::spirit::classic; Chris@16: namespace phx = phoenix; Chris@16: Chris@16: Chris@16: int_lit = ( Chris@16: sub_int_lit = Chris@16: ( ch_p('0')[self.val = 0] >> (hex_lit | oct_lit) Chris@16: | dec_lit Chris@16: ) Chris@16: >> !as_lower_d[ Chris@16: (ch_p('u')[phx::var(self.is_unsigned) = true] || ch_p('l')) Chris@16: | (ch_p('l') || ch_p('u')[phx::var(self.is_unsigned) = true]) Chris@16: ] Chris@16: , Chris@16: Chris@16: hex_lit = Chris@16: (ch_p('X') | ch_p('x')) Chris@16: >> uint_parser() Chris@16: [ Chris@16: self.val = phx::arg1, Chris@16: phx::var(self.is_unsigned) = true Chris@16: ] Chris@16: , Chris@16: Chris@16: oct_lit = Chris@16: !uint_parser() Chris@16: [ Chris@16: self.val = phx::arg1, Chris@16: phx::var(self.is_unsigned) = true Chris@16: ] Chris@16: , Chris@16: Chris@16: dec_lit = Chris@16: uint_parser() Chris@16: [ Chris@16: self.val = phx::arg1 Chris@16: ] Chris@16: ) Chris@16: ; Chris@16: Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(int_lit, TRACE_INTLIT_GRAMMAR); Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(sub_int_lit, TRACE_INTLIT_GRAMMAR); Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(hex_lit, TRACE_INTLIT_GRAMMAR); Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(oct_lit, TRACE_INTLIT_GRAMMAR); Chris@16: BOOST_SPIRIT_DEBUG_TRACE_RULE(dec_lit, TRACE_INTLIT_GRAMMAR); Chris@16: } Chris@16: Chris@16: // start rule of this grammar Chris@16: rule_t const& start() const Chris@16: { return int_lit; } Chris@16: }; Chris@16: Chris@16: bool &is_unsigned; Chris@16: }; Chris@16: Chris@16: #undef TRACE_INTLIT_GRAMMAR Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // The following function is defined here, to allow the separation of Chris@16: // the compilation of the intlit_grammar from the function using it. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 Chris@16: #define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE Chris@16: #else Chris@16: #define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE inline Chris@16: #endif Chris@16: Chris@16: template Chris@16: BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE Chris@16: uint_literal_type Chris@16: intlit_grammar_gen::evaluate(TokenT const &token, Chris@16: bool &is_unsigned) Chris@16: { Chris@16: using namespace boost::spirit::classic; Chris@16: Chris@16: intlit_grammar g(is_unsigned); Chris@16: uint_literal_type result = 0; Chris@16: typename TokenT::string_type const &token_val = token.get_value(); Chris@16: parse_info hit = Chris@16: parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]); Chris@16: Chris@16: if (!hit.hit) { Chris@16: BOOST_WAVE_THROW(preprocess_exception, ill_formed_integer_literal, Chris@16: token_val.c_str(), token.get_position()); Chris@16: } Chris@16: return result; Chris@16: } Chris@16: Chris@16: #undef BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace grammars Chris@16: } // namespace wave Chris@16: } // namespace boost Chris@16: Chris@16: // the suffix header occurs after all of the code Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: Chris@16: #endif // !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)