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> |
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(statename: state)); |
88 | } |
89 | |
90 | // create an end iterator usable for end of range checking |
91 | iterator() {} |
92 | |
93 | // (wash): < mgaunard> T it; T it2 = ++it; doesn't ocmpile |
94 | // < mgaunard> this gets fixed by adding |
95 | iterator(const base_type& base) |
96 | : base_type(base) { } |
97 | |
98 | // set the new required state for the underlying lexer object |
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 |
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 |
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> |
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> |
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> |
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 | |