| // 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(BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM) |
| #define BOOST_SPIRIT_LEX_LEXER_ITERATOR_MAR_16_2007_0353PM |
| |
| #if defined(_MSC_VER) |
| #pragma once |
| #endif |
| |
| #if defined(BOOST_SPIRIT_DEBUG) |
| #include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp> |
| #else |
| #include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp> |
| #endif |
| #include <boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp> |
| #include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp> |
| #include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp> |
| #include <boost/spirit/home/support/iterators/multi_pass.hpp> |
| |
| namespace boost { namespace spirit { namespace lex { namespace lexertl |
| { |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename FunctorData> |
| struct make_multi_pass |
| { |
| // Divide the given functor type into its components (unique and |
| // shared) and build a std::pair from these parts |
| typedef std::pair<typename FunctorData::unique |
| , typename FunctorData::shared> functor_data_type; |
| |
| // This is the result type returned from the iterator |
| typedef typename FunctorData::result_type result_type; |
| |
| // Compose the multi_pass iterator policy type from the appropriate |
| // policies |
| typedef iterator_policies::split_functor_input input_policy; |
| typedef iterator_policies::ref_counted ownership_policy; |
| #if defined(BOOST_SPIRIT_DEBUG) |
| typedef iterator_policies::buf_id_check check_policy; |
| #else |
| typedef iterator_policies::no_check check_policy; |
| #endif |
| typedef iterator_policies::split_std_deque storage_policy; |
| |
| typedef iterator_policies::default_policy< |
| ownership_policy, check_policy, input_policy, storage_policy> |
| policy_type; |
| |
| // Compose the multi_pass iterator from the policy |
| typedef spirit::multi_pass<functor_data_type, policy_type> type; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // lexer_iterator exposes an iterator for a lexertl based dfa (lexer) |
| // The template parameters have the same semantics as described for the |
| // functor above. |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Functor> |
| class iterator : public make_multi_pass<Functor>::type |
| { |
| public: |
| typedef typename Functor::unique unique_functor_type; |
| typedef typename Functor::shared shared_functor_type; |
| |
| typedef typename Functor::iterator_type base_iterator_type; |
| typedef typename Functor::result_type token_type; |
| |
| private: |
| typedef typename make_multi_pass<Functor>::functor_data_type |
| functor_type; |
| typedef typename make_multi_pass<Functor>::type base_type; |
| typedef typename Functor::char_type char_type; |
| |
| public: |
| // create a new iterator encapsulating the lexer object to be used |
| // for tokenization |
| template <typename IteratorData> |
| iterator(IteratorData const& iterdata_, base_iterator_type& first |
| , base_iterator_type const& last, char_type const* state = 0) |
| : base_type(functor_type(unique_functor_type() |
| , shared_functor_type(iterdata_, first, last))) |
| { |
| set_state(map_state(state)); |
| } |
| |
| // create an end iterator usable for end of range checking |
| iterator() {} |
| |
| // (wash): < mgaunard> T it; T it2 = ++it; doesn't ocmpile |
| // < mgaunard> this gets fixed by adding |
| iterator(const base_type& base) |
| : base_type(base) { } |
| |
| // set the new required state for the underlying lexer object |
| std::size_t set_state(std::size_t state) |
| { |
| return unique_functor_type::set_state(*this, state); |
| } |
| |
| // get the curent state for the underlying lexer object |
| std::size_t get_state() |
| { |
| return unique_functor_type::get_state(*this); |
| } |
| |
| // map the given state name to a corresponding state id as understood |
| // by the underlying lexer object |
| std::size_t map_state(char_type const* statename) |
| { |
| return (0 != statename) |
| ? unique_functor_type::map_state(*this, statename) |
| : 0; |
| } |
| }; |
| |
| }}}} |
| |
| #endif |