Chris@16: /*============================================================================= Chris@16: Boost.Wave: A Standard compliant C++ preprocessor library Chris@16: Chris@16: Definition of the lexer iterator 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_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED) Chris@16: #define CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include 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: #if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) Chris@16: #define BOOST_WAVE_EOF_PREFIX static Chris@16: #else Chris@16: #define BOOST_WAVE_EOF_PREFIX Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { Chris@16: namespace wave { Chris@16: namespace cpplexer { Chris@16: namespace impl { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // lex_iterator_functor_shim Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: template Chris@16: class lex_iterator_functor_shim Chris@16: { Chris@16: typedef typename TokenT::position_type position_type; Chris@16: Chris@16: public: Chris@16: lex_iterator_functor_shim() Chris@16: #if /*0 != __DECCXX_VER || */defined(__PGI) Chris@16: : eof() Chris@16: #endif Chris@16: {} Chris@16: Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) Chris@16: lex_iterator_functor_shim& operator= (lex_iterator_functor_shim const& rhs) Chris@16: { return *this; } // nothing to do here Chris@16: #endif Chris@16: Chris@16: // interface to the iterator_policies::split_functor_input policy Chris@16: typedef TokenT result_type; Chris@16: typedef lex_iterator_functor_shim unique; Chris@16: typedef lex_input_interface* shared; Chris@16: Chris@16: BOOST_WAVE_EOF_PREFIX result_type const eof; Chris@16: Chris@16: template Chris@16: static result_type& get_next(MultiPass& mp, result_type& result) Chris@16: { Chris@16: return mp.shared()->ftor->get(result); Chris@16: } Chris@16: Chris@16: // this will be called whenever the last reference to a multi_pass will Chris@16: // be released Chris@16: template Chris@16: static void destroy(MultiPass& mp) Chris@16: { Chris@16: delete mp.shared()->ftor; Chris@16: } Chris@16: Chris@16: template Chris@16: static void set_position(MultiPass& mp, position_type const &pos) Chris@16: { Chris@16: mp.shared()->ftor->set_position(pos); Chris@16: } Chris@16: #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 Chris@16: template Chris@16: static bool has_include_guards(MultiPass& mp, std::string& guard_name) Chris@16: { Chris@16: return mp.shared()->ftor->has_include_guards(guard_name); Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // eof token Chris@16: #if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) Chris@16: template Chris@16: typename lex_iterator_functor_shim::result_type const Chris@16: lex_iterator_functor_shim::eof; Chris@16: #endif // 0 != __COMO_VERSION__ Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace impl Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // lex_iterator Chris@16: // Chris@16: // A generic C++ lexer interface class, which allows to plug in different Chris@16: // lexer implementations. The interface between the lexer type used and Chris@16: // the preprocessor component depends on the token type only (template Chris@16: // parameter TokenT). Chris@16: // Additionally, the following requirements apply: Chris@16: // Chris@16: // - the lexer type should have a function implemented, which returnes Chris@16: // the next lexed token from the input stream: Chris@16: // typename TokenT get(); Chris@16: // - at the end of the input stream this function should return the Chris@16: // eof token equivalent Chris@16: // - the lexer should implement a constructor taking two iterators Chris@16: // pointing to the beginning and the end of the input stream, Chris@16: // a third parameter containing the name of the parsed input file Chris@16: // and a 4th parameter of the type boost::wave::language_support Chris@16: // which specifies, which language subset should be supported (C++, Chris@16: // C99, C++11 etc.). Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Divide the given functor type into its components (unique and shared) Chris@16: // and build a std::pair from these parts Chris@16: template Chris@16: struct make_multi_pass Chris@16: { Chris@16: typedef Chris@16: std::pair Chris@16: functor_data_type; Chris@16: typedef typename FunctorData::result_type result_type; Chris@16: Chris@16: typedef boost::spirit::iterator_policies::split_functor_input input_policy; Chris@16: typedef boost::spirit::iterator_policies::ref_counted ownership_policy; Chris@16: #if defined(BOOST_WAVE_DEBUG) Chris@16: typedef boost::spirit::iterator_policies::buf_id_check check_policy; Chris@16: #else Chris@16: typedef boost::spirit::iterator_policies::no_check check_policy; Chris@16: #endif Chris@16: typedef boost::spirit::iterator_policies::split_std_deque storage_policy; Chris@16: Chris@16: typedef boost::spirit::iterator_policies::default_policy< Chris@16: ownership_policy, check_policy, input_policy, storage_policy> Chris@16: policy_type; Chris@16: typedef boost::spirit::multi_pass type; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: class lex_iterator Chris@16: : public make_multi_pass >::type Chris@16: { Chris@16: typedef impl::lex_iterator_functor_shim input_policy_type; Chris@16: Chris@16: typedef typename make_multi_pass::type base_type; Chris@16: typedef typename make_multi_pass::functor_data_type Chris@16: functor_data_type; Chris@16: Chris@16: typedef typename input_policy_type::unique unique_functor_type; Chris@16: typedef typename input_policy_type::shared shared_functor_type; Chris@16: Chris@16: public: Chris@16: typedef TokenT token_type; Chris@16: Chris@16: lex_iterator() Chris@16: {} Chris@16: Chris@16: template Chris@16: lex_iterator(IteratorT const &first, IteratorT const &last, Chris@16: typename TokenT::position_type const &pos, Chris@16: boost::wave::language_support language) Chris@16: : base_type( Chris@16: functor_data_type( Chris@16: unique_functor_type(), Chris@16: lex_input_interface_generator Chris@16: ::new_lexer(first, last, pos, language) Chris@16: ) Chris@16: ) Chris@16: {} Chris@16: Chris@16: void set_position(typename TokenT::position_type const &pos) Chris@16: { Chris@16: typedef typename TokenT::position_type position_type; Chris@16: Chris@16: // set the new position in the current token Chris@16: token_type const& currtoken = this->base_type::dereference(*this); Chris@16: position_type currpos = currtoken.get_position(); Chris@16: Chris@16: currpos.set_file(pos.get_file()); Chris@16: currpos.set_line(pos.get_line()); Chris@16: const_cast(currtoken).set_position(currpos); Chris@16: Chris@16: // set the new position for future tokens as well Chris@16: if (token_type::string_type::npos != Chris@16: currtoken.get_value().find_first_of('\n')) Chris@16: { Chris@16: currpos.set_line(pos.get_line() + 1); Chris@16: } Chris@16: unique_functor_type::set_position(*this, currpos); Chris@16: } Chris@16: Chris@16: #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 Chris@16: // return, whether the current file has include guards Chris@16: // this function returns meaningful results only if the file was scanned Chris@16: // completely Chris@16: bool has_include_guards(std::string& guard_name) const Chris@16: { Chris@16: return unique_functor_type::has_include_guards(*this, guard_name); Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace cpplexer 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: #undef BOOST_WAVE_EOF_PREFIX Chris@16: Chris@16: #endif // !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED)