File indexing completed on 2025-01-31 10:02:15
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_LEX_LEXER_FUNCTOR_NOV_18_2007_1112PM)
0007 #define BOOST_SPIRIT_LEX_LEXER_FUNCTOR_NOV_18_2007_1112PM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/mpl/bool.hpp>
0014 #include <boost/detail/workaround.hpp>
0015 #include <boost/spirit/home/lex/lexer/pass_flags.hpp>
0016 #include <boost/assert.hpp>
0017 #include <iterator> // for std::iterator_traits
0018
0019 #if 0 != __COMO_VERSION__ || !BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
0020 #define BOOST_SPIRIT_STATIC_EOF 1
0021 #define BOOST_SPIRIT_EOF_PREFIX static
0022 #else
0023 #define BOOST_SPIRIT_EOF_PREFIX
0024 #endif
0025
0026 namespace boost { namespace spirit { namespace lex { namespace lexertl
0027 {
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 template <typename Token
0061 , template <typename, typename, typename, typename> class FunctorData
0062 , typename Iterator = typename Token::iterator_type
0063 , typename SupportsActors = mpl::false_
0064 , typename SupportsState = typename Token::has_state>
0065 class functor
0066 {
0067 public:
0068 typedef typename
0069 std::iterator_traits<Iterator>::value_type
0070 char_type;
0071
0072 private:
0073
0074
0075
0076 typedef typename Token::token_value_type token_value_type;
0077 friend class FunctorData<Iterator, SupportsActors, SupportsState
0078 , token_value_type>;
0079
0080 #ifdef _MSC_VER
0081 # pragma warning(push)
0082 # pragma warning(disable: 4512)
0083 #endif
0084
0085 template <typename T>
0086 struct assign_on_exit
0087 {
0088 assign_on_exit(T& dst, T const& src)
0089 : dst_(dst), src_(src) {}
0090
0091 ~assign_on_exit()
0092 {
0093 dst_ = src_;
0094 }
0095
0096 T& dst_;
0097 T const& src_;
0098 };
0099 #ifdef _MSC_VER
0100 # pragma warning(pop)
0101 #endif
0102
0103 public:
0104 functor() {}
0105
0106 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
0107
0108 functor& operator=(functor const& rhs)
0109 {
0110 return *this;
0111 }
0112 #endif
0113
0114
0115
0116 typedef Token result_type;
0117 typedef functor unique;
0118 typedef FunctorData<Iterator, SupportsActors, SupportsState
0119 , token_value_type> shared;
0120
0121 BOOST_SPIRIT_EOF_PREFIX result_type const eof;
0122
0123
0124 typedef Iterator iterator_type;
0125 typedef typename shared::semantic_actions_type semantic_actions_type;
0126 typedef typename shared::next_token_functor next_token_functor;
0127 typedef typename shared::get_state_name_type get_state_name_type;
0128
0129
0130 typedef typename shared::wrap_action_type wrap_action_type;
0131
0132
0133 template <typename MultiPass>
0134 static result_type& get_next(MultiPass& mp, result_type& result)
0135 {
0136 typedef typename result_type::id_type id_type;
0137
0138 shared& data = mp.shared()->ftor;
0139 for(;;)
0140 {
0141 if (data.get_first() == data.get_last())
0142 #if defined(BOOST_SPIRIT_STATIC_EOF)
0143 return result = eof;
0144 #else
0145 return result = mp.ftor.eof;
0146 #endif
0147
0148 data.reset_value();
0149 Iterator end = data.get_first();
0150 std::size_t unique_id = boost::lexer::npos;
0151 bool prev_bol = false;
0152
0153
0154 std::size_t state = data.get_state();
0155 std::size_t id = data.next(end, unique_id, prev_bol);
0156
0157 if (boost::lexer::npos == id) {
0158 #if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
0159 std::string next;
0160 Iterator it = data.get_first();
0161 for (std::size_t i = 0; i < 10 && it != data.get_last(); ++it, ++i)
0162 next += *it;
0163
0164 std::cerr << "Not matched, in state: " << state
0165 << ", lookahead: >" << next << "<" << std::endl;
0166 #endif
0167 return result = result_type(0);
0168 }
0169 else if (0 == id) {
0170 #if defined(BOOST_SPIRIT_STATIC_EOF)
0171 return result = eof;
0172 #else
0173 return result = mp.ftor.eof;
0174 #endif
0175 }
0176
0177 #if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
0178 {
0179 std::string next;
0180 Iterator it = end;
0181 for (std::size_t i = 0; i < 10 && it != data.get_last(); ++it, ++i)
0182 next += *it;
0183
0184 std::cerr << "Matched: " << id << ", in state: "
0185 << state << ", string: >"
0186 << std::basic_string<char_type>(data.get_first(), end) << "<"
0187 << ", lookahead: >" << next << "<" << std::endl;
0188 if (data.get_state() != state) {
0189 std::cerr << "Switched to state: "
0190 << data.get_state() << std::endl;
0191 }
0192 }
0193 #endif
0194
0195
0196 bool adjusted = data.adjust_start();
0197
0198
0199 data.set_end(end);
0200
0201
0202
0203 BOOST_SCOPED_ENUM(pass_flags) pass =
0204 data.invoke_actions(state, id, unique_id, end);
0205
0206 if (data.has_value()) {
0207
0208
0209
0210 assign_on_exit<Iterator> on_exit(data.get_first(), end);
0211 return result = result_type(id_type(id), state, data.get_value());
0212 }
0213 else if (pass_flags::pass_normal == pass) {
0214
0215
0216 assign_on_exit<Iterator> on_exit(data.get_first(), end);
0217 return result = result_type(id_type(id), state, data.get_first(), end);
0218 }
0219 else if (pass_flags::pass_fail == pass) {
0220 #if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
0221 std::cerr << "Matching forced to fail" << std::endl;
0222 #endif
0223
0224 if (adjusted)
0225 data.revert_adjust_start();
0226
0227
0228 data.reset_bol(prev_bol);
0229 if (state != data.get_state())
0230 continue;
0231
0232
0233
0234 return result = result_type(0);
0235 }
0236
0237 #if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
0238 std::cerr << "Token ignored, continuing matching" << std::endl;
0239 #endif
0240
0241
0242 data.get_first() = end;
0243 }
0244 }
0245
0246
0247
0248
0249 template <typename MultiPass>
0250 static std::size_t set_state(MultiPass& mp, std::size_t state)
0251 {
0252 std::size_t oldstate = mp.shared()->ftor.get_state();
0253 mp.shared()->ftor.set_state(state);
0254
0255 #if defined(BOOST_SPIRIT_LEXERTL_DEBUG)
0256 std::cerr << "Switching state from: " << oldstate
0257 << " to: " << state
0258 << std::endl;
0259 #endif
0260 return oldstate;
0261 }
0262
0263 template <typename MultiPass>
0264 static std::size_t get_state(MultiPass& mp)
0265 {
0266 return mp.shared()->ftor.get_state();
0267 }
0268
0269 template <typename MultiPass>
0270 static std::size_t
0271 map_state(MultiPass const& mp, char_type const* statename)
0272 {
0273 return mp.shared()->ftor.get_state_id(statename);
0274 }
0275
0276
0277 template <typename MultiPass>
0278 static void destroy(MultiPass const&) {}
0279 };
0280
0281 #if defined(BOOST_SPIRIT_STATIC_EOF)
0282
0283
0284
0285 template <typename Token
0286 , template <typename, typename, typename, typename> class FunctorData
0287 , typename Iterator, typename SupportsActors, typename SupportsState>
0288 typename functor<Token, FunctorData, Iterator, SupportsActors, SupportsState>::result_type const
0289 functor<Token, FunctorData, Iterator, SupportsActors, SupportsState>::eof =
0290 typename functor<Token, FunctorData, Iterator, SupportsActors
0291 , SupportsState>::result_type();
0292 #endif
0293
0294 }}}}
0295
0296 #undef BOOST_SPIRIT_EOF_PREFIX
0297 #undef BOOST_SPIRIT_STATIC_EOF
0298
0299 #endif