]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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(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 curent 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 |