diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /boost/wave/cpplexer/cpp_lex_iterator.hpp | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'boost/wave/cpplexer/cpp_lex_iterator.hpp')
-rw-r--r-- | boost/wave/cpplexer/cpp_lex_iterator.hpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/boost/wave/cpplexer/cpp_lex_iterator.hpp b/boost/wave/cpplexer/cpp_lex_iterator.hpp new file mode 100644 index 0000000000..fe93888af5 --- /dev/null +++ b/boost/wave/cpplexer/cpp_lex_iterator.hpp @@ -0,0 +1,243 @@ +/*============================================================================= + Boost.Wave: A Standard compliant C++ preprocessor library + + Definition of the lexer iterator + + http://www.boost.org/ + + Copyright (c) 2001-2011 Hartmut Kaiser. Distributed under the Boost + Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#if !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED) +#define CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED + +#include <string> + +#include <boost/assert.hpp> +#include <boost/intrusive_ptr.hpp> + +#include <boost/wave/wave_config.hpp> +#include <boost/spirit/include/support_multi_pass.hpp> + +#include <boost/wave/util/file_position.hpp> +#include <boost/wave/util/functor_input.hpp> +#include <boost/wave/cpplexer/cpp_lex_interface_generator.hpp> + +#include <boost/wave/language_support.hpp> + +// this must occur after all of the includes and before any code appears +#ifdef BOOST_HAS_ABI_HEADERS +#include BOOST_ABI_PREFIX +#endif + +#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) +#define BOOST_WAVE_EOF_PREFIX static +#else +#define BOOST_WAVE_EOF_PREFIX +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { +namespace wave { +namespace cpplexer { +namespace impl { + +/////////////////////////////////////////////////////////////////////////////// +// +// lex_iterator_functor_shim +// +/////////////////////////////////////////////////////////////////////////////// + +template <typename TokenT> +class lex_iterator_functor_shim +{ + typedef typename TokenT::position_type position_type; + +public: + lex_iterator_functor_shim() +#if /*0 != __DECCXX_VER || */defined(__PGI) + : eof() +#endif + {} + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) + lex_iterator_functor_shim& operator= (lex_iterator_functor_shim const& rhs) + { return *this; } // nothing to do here +#endif + +// interface to the iterator_policies::split_functor_input policy + typedef TokenT result_type; + typedef lex_iterator_functor_shim unique; + typedef lex_input_interface<TokenT>* shared; + + BOOST_WAVE_EOF_PREFIX result_type const eof; + + template <typename MultiPass> + static result_type& get_next(MultiPass& mp, result_type& result) + { + return mp.shared()->ftor->get(result); + } + + // this will be called whenever the last reference to a multi_pass will + // be released + template <typename MultiPass> + static void destroy(MultiPass& mp) + { + delete mp.shared()->ftor; + } + + template <typename MultiPass> + static void set_position(MultiPass& mp, position_type const &pos) + { + mp.shared()->ftor->set_position(pos); + } +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 + template <typename MultiPass> + static bool has_include_guards(MultiPass& mp, std::string& guard_name) + { + return mp.shared()->ftor->has_include_guards(guard_name); + } +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// +// eof token +#if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) +template <typename TokenT> +typename lex_iterator_functor_shim<TokenT>::result_type const + lex_iterator_functor_shim<TokenT>::eof; +#endif // 0 != __COMO_VERSION__ + +/////////////////////////////////////////////////////////////////////////////// +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +// +// lex_iterator +// +// A generic C++ lexer interface class, which allows to plug in different +// lexer implementations. The interface between the lexer type used and +// the preprocessor component depends on the token type only (template +// parameter TokenT). +// Additionally, the following requirements apply: +// +// - the lexer type should have a function implemented, which returnes +// the next lexed token from the input stream: +// typename TokenT get(); +// - at the end of the input stream this function should return the +// eof token equivalent +// - the lexer should implement a constructor taking two iterators +// pointing to the beginning and the end of the input stream, +// a third parameter containing the name of the parsed input file +// and a 4th parameter of the type boost::wave::language_support +// which specifies, which language subset should be supported (C++, +// C99, C++0x etc.). +// +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Divide the given functor type into its components (unique and shared) +// and build a std::pair from these parts +template <typename FunctorData> +struct make_multi_pass +{ + typedef + std::pair<typename FunctorData::unique, typename FunctorData::shared> + functor_data_type; + typedef typename FunctorData::result_type result_type; + + typedef boost::spirit::iterator_policies::split_functor_input input_policy; + typedef boost::spirit::iterator_policies::ref_counted ownership_policy; +#if defined(BOOST_WAVE_DEBUG) + typedef boost::spirit::iterator_policies::buf_id_check check_policy; +#else + typedef boost::spirit::iterator_policies::no_check check_policy; +#endif + typedef boost::spirit::iterator_policies::split_std_deque storage_policy; + + typedef boost::spirit::iterator_policies::default_policy< + ownership_policy, check_policy, input_policy, storage_policy> + policy_type; + typedef boost::spirit::multi_pass<functor_data_type, policy_type> type; +}; + +/////////////////////////////////////////////////////////////////////////////// +template <typename TokenT> +class lex_iterator +: public make_multi_pass<impl::lex_iterator_functor_shim<TokenT> >::type +{ + typedef impl::lex_iterator_functor_shim<TokenT> input_policy_type; + + typedef typename make_multi_pass<input_policy_type>::type base_type; + typedef typename make_multi_pass<input_policy_type>::functor_data_type + functor_data_type; + + typedef typename input_policy_type::unique unique_functor_type; + typedef typename input_policy_type::shared shared_functor_type; + +public: + typedef TokenT token_type; + + lex_iterator() + {} + + template <typename IteratorT> + lex_iterator(IteratorT const &first, IteratorT const &last, + typename TokenT::position_type const &pos, + boost::wave::language_support language) + : base_type( + functor_data_type( + unique_functor_type(), + lex_input_interface_generator<TokenT> + ::new_lexer(first, last, pos, language) + ) + ) + {} + + void set_position(typename TokenT::position_type const &pos) + { + typedef typename TokenT::position_type position_type; + + // set the new position in the current token + token_type const& currtoken = this->base_type::dereference(*this); + position_type currpos = currtoken.get_position(); + + currpos.set_file(pos.get_file()); + currpos.set_line(pos.get_line()); + const_cast<token_type&>(currtoken).set_position(currpos); + + // set the new position for future tokens as well + if (token_type::string_type::npos != + currtoken.get_value().find_first_of('\n')) + { + currpos.set_line(pos.get_line() + 1); + } + unique_functor_type::set_position(*this, currpos); + } + +#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 + // return, whether the current file has include guards + // this function returns meaningful results only if the file was scanned + // completely + bool has_include_guards(std::string& guard_name) const + { + return unique_functor_type::has_include_guards(*this, guard_name); + } +#endif +}; + +/////////////////////////////////////////////////////////////////////////////// +} // namespace cpplexer +} // namespace wave +} // namespace boost + +// the suffix header occurs after all of the code +#ifdef BOOST_HAS_ABI_HEADERS +#include BOOST_ABI_SUFFIX +#endif + +#undef BOOST_WAVE_EOF_PREFIX + +#endif // !defined(CPP_LEX_ITERATOR_HPP_AF0C37E3_CBD8_4F33_A225_51CF576FA61F_INCLUDED) |