1 /*============================================================================= 2 Boost.Wave: A Standard compliant C++ preprocessor library 3 4 Sample: Re2C based IDL lexer 5 Definition of the lexer iterator 6 7 http://www.boost.org/ 8 9 Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost 10 Software License, Version 1.0. (See accompanying file 11 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 12 =============================================================================*/ 13 14 #if !defined(IDL_LEX_ITERATOR_HPP_7926F865_E02F_4950_9EB5_5F453C9FF953_INCLUDED) 15 #define IDL_LEX_ITERATOR_HPP_7926F865_E02F_4950_9EB5_5F453C9FF953_INCLUDED 16 17 #include <string> 18 #include <iosfwd> 19 20 #include <boost/assert.hpp> 21 #include <boost/shared_ptr.hpp> 22 #include <boost/spirit/include/support_multi_pass.hpp> 23 24 #include <boost/wave/language_support.hpp> 25 #include <boost/wave/util/file_position.hpp> 26 #include <boost/wave/util/functor_input.hpp> 27 28 #include "idl_lex_interface.hpp" 29 30 #if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) 31 #define BOOST_WAVE_EOF_PREFIX static 32 #else 33 #define BOOST_WAVE_EOF_PREFIX 34 #endif 35 36 /////////////////////////////////////////////////////////////////////////////// 37 namespace boost { 38 namespace wave { 39 namespace idllexer { 40 namespace impl { 41 42 /////////////////////////////////////////////////////////////////////////////// 43 // 44 // lex_iterator_functor_shim 45 // 46 /////////////////////////////////////////////////////////////////////////////// 47 48 template <typename TokenT> 49 class lex_iterator_functor_shim 50 { 51 typedef typename TokenT::position_type position_type; 52 53 public: lex_iterator_functor_shim()54 lex_iterator_functor_shim() 55 #if /*0 != __DECCXX_VER || */defined(__PGI) 56 : eof() 57 #endif // 0 != __DECCXX_VER 58 {} 59 60 // interface to the boost::spirit::classic::iterator_policies::functor_input 61 // policy 62 typedef TokenT result_type; 63 64 BOOST_WAVE_EOF_PREFIX result_type const eof; 65 typedef lex_iterator_functor_shim unique; 66 typedef cpplexer::lex_input_interface<TokenT>* shared; 67 68 template <typename MultiPass> get_next(MultiPass & mp,result_type & result)69 static result_type& get_next(MultiPass& mp, result_type& result) 70 { 71 return mp.shared()->ftor->get(result); 72 } 73 74 // this will be called whenever the last reference to a multi_pass will 75 // be released 76 template <typename MultiPass> destroy(MultiPass & mp)77 static void destroy(MultiPass& mp) 78 { 79 delete mp.shared()->ftor; 80 } 81 82 template <typename MultiPass> set_position(MultiPass & mp,position_type const & pos)83 static void set_position(MultiPass& mp, position_type const &pos) 84 { 85 mp.shared()->ftor->set_position(pos); 86 } 87 88 private: 89 boost::shared_ptr<cpplexer::lex_input_interface<TokenT> > functor_ptr; 90 }; 91 92 #if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) 93 /////////////////////////////////////////////////////////////////////////////// 94 // eof token 95 template <typename TokenT> 96 typename lex_iterator_functor_shim<TokenT>::result_type const 97 lex_iterator_functor_shim<TokenT>::eof = 98 typename lex_iterator_functor_shim<TokenT>::result_type(); 99 #endif // 0 != __COMO_VERSION__ 100 101 /////////////////////////////////////////////////////////////////////////////// 102 } // namespace impl 103 104 /////////////////////////////////////////////////////////////////////////////// 105 // 106 // lex_iterator 107 // 108 // A generic C++ lexer interface class, which allows to plug in different 109 // lexer implementations (template parameter LexT). The following 110 // requirement apply: 111 // 112 // - the lexer type should have a function implemented, which returnes 113 // the next lexed token from the input stream: 114 // typename LexT::token_type get(); 115 // - at the end of the input stream this function should return the 116 // eof token equivalent 117 // - the lexer should implement a constructor taking two iterators 118 // pointing to the beginning and the end of the input stream and 119 // a third parameter containing the name of the parsed input file 120 // 121 /////////////////////////////////////////////////////////////////////////////// 122 123 /////////////////////////////////////////////////////////////////////////////// 124 // Divide the given functor type into its components (unique and shared) 125 // and build a std::pair from these parts 126 template <typename FunctorData> 127 struct make_multi_pass 128 { 129 typedef 130 std::pair<typename FunctorData::unique, typename FunctorData::shared> 131 functor_data_type; 132 typedef typename FunctorData::result_type result_type; 133 134 typedef boost::spirit::iterator_policies::split_functor_input input_policy; 135 typedef boost::spirit::iterator_policies::ref_counted ownership_policy; 136 #if defined(BOOST_WAVE_DEBUG) 137 typedef boost::spirit::iterator_policies::buf_id_check check_policy; 138 #else 139 typedef boost::spirit::iterator_policies::no_check check_policy; 140 #endif 141 typedef boost::spirit::iterator_policies::split_std_deque storage_policy; 142 143 typedef boost::spirit::iterator_policies::default_policy< 144 ownership_policy, check_policy, input_policy, storage_policy> 145 policy_type; 146 typedef boost::spirit::multi_pass<functor_data_type, policy_type> type; 147 }; 148 149 /////////////////////////////////////////////////////////////////////////////// 150 template <typename TokenT> 151 class lex_iterator 152 : public make_multi_pass<impl::lex_iterator_functor_shim<TokenT> >::type 153 { 154 typedef impl::lex_iterator_functor_shim<TokenT> input_policy_type; 155 156 typedef typename make_multi_pass<input_policy_type>::type base_type; 157 typedef typename make_multi_pass<input_policy_type>::functor_data_type 158 functor_data_type; 159 160 typedef typename input_policy_type::unique unique_functor_type; 161 typedef typename input_policy_type::shared shared_functor_type; 162 163 public: 164 typedef TokenT token_type; 165 lex_iterator()166 lex_iterator() 167 {} 168 169 template <typename IteratorT> lex_iterator(IteratorT const & first,IteratorT const & last,typename TokenT::position_type const & pos,boost::wave::language_support language)170 lex_iterator(IteratorT const &first, IteratorT const &last, 171 typename TokenT::position_type const &pos, 172 boost::wave::language_support language) 173 : base_type( 174 functor_data_type( 175 unique_functor_type(), 176 idllexer::lex_input_interface_generator<TokenT> 177 ::new_lexer(first, last, pos, language) 178 ) 179 ) 180 {} 181 set_position(typename TokenT::position_type const & pos)182 void set_position(typename TokenT::position_type const &pos) 183 { 184 typedef typename TokenT::position_type position_type; 185 186 // set the new position in the current token 187 token_type const& currtoken = this->base_type::dereference(*this); 188 position_type currpos = currtoken.get_position(); 189 currpos.set_file(pos.get_file()); 190 currpos.set_line(pos.get_line()); 191 const_cast<token_type&>(currtoken).set_position(currpos); 192 193 // set the new position for future tokens as well 194 unique_functor_type::set_position(*this, currpos); 195 } 196 197 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0 198 // this sample does no include guard detection has_include_guards(std::string &) const199 bool has_include_guards(std::string&) const { return false; } 200 #endif 201 }; 202 203 /////////////////////////////////////////////////////////////////////////////// 204 } // namespace idllexer 205 } // namespace wave 206 } // namespace boost 207 208 #undef BOOST_WAVE_EOF_PREFIX 209 210 #endif // !defined(IDL_LEX_ITERATOR_HPP_7926F865_E02F_4950_9EB5_5F453C9FF953_INCLUDED) 211