iterator.hpp 5.3 KB

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