1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM) 7 #define BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM 8 9 #if defined(_MSC_VER) 10 #pragma once 11 #endif 12 13 #include <boost/spirit/home/support/multi_pass_wrapper.hpp> 14 #if defined(BOOST_SPIRIT_DEBUG) 15 #include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp> 16 #else 17 #include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp> 18 #endif 19 #include <boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp> 20 #include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp> 21 #include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp> 22 #include <boost/spirit/home/support/iterators/multi_pass.hpp> 23 24 namespace boost { namespace spirit { namespace lex { namespace lexertl 25 { 26 /////////////////////////////////////////////////////////////////////////// 27 template <typename FunctorData> 28 struct make_multi_pass 29 { 30 // Divide the given functor type into its components (unique and 31 // shared) and build a std::pair from these parts 32 typedef std::pair<typename FunctorData::unique 33 , typename FunctorData::shared> functor_data_type; 34 35 // This is the result type returned from the iterator 36 typedef typename FunctorData::result_type result_type; 37 38 // Compose the multi_pass iterator policy type from the appropriate 39 // policies 40 typedef iterator_policies::split_functor_input input_policy; 41 typedef iterator_policies::ref_counted ownership_policy; 42 #if defined(BOOST_SPIRIT_DEBUG) 43 typedef iterator_policies::buf_id_check check_policy; 44 #else 45 typedef iterator_policies::no_check check_policy; 46 #endif 47 typedef iterator_policies::split_std_deque storage_policy; 48 49 typedef iterator_policies::default_policy< 50 ownership_policy, check_policy, input_policy, storage_policy> 51 policy_type; 52 53 // Compose the multi_pass iterator from the policy 54 typedef spirit::multi_pass<functor_data_type, policy_type> type; 55 }; 56 57 /////////////////////////////////////////////////////////////////////////// 58 // lexer_iterator exposes an iterator for a lexertl based dfa (lexer) 59 // The template parameters have the same semantics as described for the 60 // functor above. 61 /////////////////////////////////////////////////////////////////////////// 62 template <typename Functor> 63 class iterator : public make_multi_pass<Functor>::type 64 { 65 public: 66 typedef typename Functor::unique unique_functor_type; 67 typedef typename Functor::shared shared_functor_type; 68 69 typedef typename Functor::iterator_type base_iterator_type; 70 typedef typename Functor::result_type token_type; 71 72 private: 73 typedef typename make_multi_pass<Functor>::functor_data_type 74 functor_type; 75 typedef typename make_multi_pass<Functor>::type base_type; 76 typedef typename Functor::char_type char_type; 77 78 public: 79 // create a new iterator encapsulating the lexer object to be used 80 // for tokenization 81 template <typename IteratorData> iterator(IteratorData const & iterdata_,base_iterator_type & first,base_iterator_type const & last,char_type const * state=0)82 iterator(IteratorData const& iterdata_, base_iterator_type& first 83 , base_iterator_type const& last, char_type const* state = 0) 84 : base_type(functor_type(unique_functor_type() 85 , shared_functor_type(iterdata_, first, last))) 86 { 87 set_state(map_state(state)); 88 } 89 90 // create an end iterator usable for end of range checking iterator()91 iterator() {} 92 93 // (wash): < mgaunard> T it; T it2 = ++it; doesn't ocmpile 94 // < mgaunard> this gets fixed by adding iterator(const base_type & base)95 iterator(const base_type& base) 96 : base_type(base) { } 97 98 // set the new required state for the underlying lexer object set_state(std::size_t state)99 std::size_t set_state(std::size_t state) 100 { 101 return unique_functor_type::set_state(*this, state); 102 } 103 104 // get the current state for the underlying lexer object get_state()105 std::size_t get_state() 106 { 107 return unique_functor_type::get_state(*this); 108 } 109 110 // map the given state name to a corresponding state id as understood 111 // by the underlying lexer object map_state(char_type const * statename)112 std::size_t map_state(char_type const* statename) 113 { 114 return (0 != statename) 115 ? unique_functor_type::map_state(*this, statename) 116 : 0; 117 } 118 }; 119 }} 120 121 namespace traits 122 { 123 template <typename Functor> 124 struct is_multi_pass<spirit::lex::lexertl::iterator<Functor> > 125 : mpl::true_ {}; 126 127 template <typename Functor> clear_queue(spirit::lex::lexertl::iterator<Functor> & mp,BOOST_SCOPED_ENUM (traits::clear_mode)mode)128 void clear_queue(spirit::lex::lexertl::iterator<Functor> & mp 129 , BOOST_SCOPED_ENUM(traits::clear_mode) mode) 130 { 131 mp.clear_queue(mode); 132 } 133 134 template <typename Functor> inhibit_clear_queue(spirit::lex::lexertl::iterator<Functor> & mp,bool flag)135 void inhibit_clear_queue(spirit::lex::lexertl::iterator<Functor>& mp, bool flag) 136 { 137 mp.inhibit_clear_queue(flag); 138 } 139 140 template <typename Functor> inhibit_clear_queue(spirit::lex::lexertl::iterator<Functor> & mp)141 bool inhibit_clear_queue(spirit::lex::lexertl::iterator<Functor>& mp) 142 { 143 return mp.inhibit_clear_queue(); 144 } 145 } 146 147 }} 148 149 #endif 150