token.hpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  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_TOKEN_FEB_10_2008_0751PM)
  6. #define BOOST_SPIRIT_LEX_TOKEN_FEB_10_2008_0751PM
  7. #if defined(_MSC_VER)
  8. #pragma once
  9. #endif
  10. #include <boost/config.hpp>
  11. #include <boost/detail/workaround.hpp>
  12. #include <boost/spirit/home/qi/detail/assign_to.hpp>
  13. #include <boost/spirit/home/support/attributes.hpp>
  14. #include <boost/spirit/home/support/argument.hpp>
  15. #include <boost/spirit/home/support/detail/lexer/generator.hpp>
  16. #include <boost/spirit/home/support/detail/lexer/rules.hpp>
  17. #include <boost/spirit/home/support/detail/lexer/consts.hpp>
  18. #include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
  19. #include <boost/spirit/home/lex/lexer/terminals.hpp>
  20. #include <boost/fusion/include/vector.hpp>
  21. #include <boost/fusion/include/at.hpp>
  22. #include <boost/fusion/include/value_at.hpp>
  23. #include <boost/variant.hpp>
  24. #include <boost/mpl/bool.hpp>
  25. #include <boost/mpl/vector.hpp>
  26. #include <boost/mpl/is_sequence.hpp>
  27. #include <boost/mpl/begin.hpp>
  28. #include <boost/mpl/insert.hpp>
  29. #include <boost/mpl/vector.hpp>
  30. #include <boost/mpl/if.hpp>
  31. #include <boost/mpl/or.hpp>
  32. #include <boost/range/iterator_range_core.hpp>
  33. #include <boost/type_traits/is_same.hpp>
  34. #include <boost/type_traits/make_unsigned.hpp>
  35. #include <boost/static_assert.hpp>
  36. #if defined(BOOST_SPIRIT_DEBUG)
  37. #include <iosfwd>
  38. #endif
  39. namespace boost { namespace spirit { namespace lex { namespace lexertl
  40. {
  41. ///////////////////////////////////////////////////////////////////////////
  42. //
  43. // The token is the type of the objects returned by default by the
  44. // iterator.
  45. //
  46. // template parameters:
  47. // Iterator The type of the iterator used to access the
  48. // underlying character stream.
  49. // AttributeTypes A mpl sequence containing the types of all
  50. // required different token values to be supported
  51. // by this token type.
  52. // HasState A mpl::bool_ indicating, whether this token type
  53. // should support lexer states.
  54. // Idtype The type to use for the token id (defaults to
  55. // std::size_t).
  56. //
  57. // It is possible to use other token types with the spirit::lex
  58. // framework as well. If you plan to use a different type as your token
  59. // type, you'll need to expose the following things from your token type
  60. // to make it compatible with spirit::lex:
  61. //
  62. // typedefs
  63. // iterator_type The type of the iterator used to access the
  64. // underlying character stream.
  65. //
  66. // id_type The type of the token id used.
  67. //
  68. // methods
  69. // default constructor
  70. // This should initialize the token as an end of
  71. // input token.
  72. // constructors The prototype of the other required
  73. // constructors should be:
  74. //
  75. // token(int)
  76. // This constructor should initialize the token as
  77. // an invalid token (not carrying any specific
  78. // values)
  79. //
  80. // where: the int is used as a tag only and its value is
  81. // ignored
  82. //
  83. // and:
  84. //
  85. // token(Idtype id, std::size_t state,
  86. // iterator_type first, iterator_type last);
  87. //
  88. // where: id: token id
  89. // state: lexer state this token was matched in
  90. // first, last: pair of iterators marking the matched
  91. // range in the underlying input stream
  92. //
  93. // accessors
  94. // id() return the token id of the matched input sequence
  95. // id(newid) set the token id of the token instance
  96. //
  97. // state() return the lexer state this token was matched in
  98. //
  99. // value() return the token value
  100. //
  101. // Additionally, you will have to implement a couple of helper functions
  102. // in the same namespace as the token type: a comparison operator==() to
  103. // compare your token instances, a token_is_valid() function and different
  104. // specializations of the Spirit customization point
  105. // assign_to_attribute_from_value as shown below.
  106. //
  107. ///////////////////////////////////////////////////////////////////////////
  108. template <typename Iterator = char const*
  109. , typename AttributeTypes = mpl::vector0<>
  110. , typename HasState = mpl::true_
  111. , typename Idtype = std::size_t>
  112. struct token;
  113. ///////////////////////////////////////////////////////////////////////////
  114. // This specialization of the token type doesn't contain any item data and
  115. // doesn't support working with lexer states.
  116. ///////////////////////////////////////////////////////////////////////////
  117. template <typename Iterator, typename Idtype>
  118. struct token<Iterator, lex::omit, mpl::false_, Idtype>
  119. {
  120. typedef Iterator iterator_type;
  121. typedef mpl::false_ has_state;
  122. typedef Idtype id_type;
  123. typedef unused_type token_value_type;
  124. typedef typename make_unsigned<id_type>::type uid_type;
  125. // default constructed tokens correspond to EOI tokens
  126. token() : id_(boost::lexer::npos) {}
  127. // construct an invalid token
  128. explicit token(int) : id_(0) {}
  129. token(id_type id, std::size_t) : id_(id) {}
  130. token(id_type id, std::size_t, token_value_type)
  131. : id_(id) {}
  132. token_value_type& value() { static token_value_type u; return u; }
  133. token_value_type const& value() const { return unused; }
  134. #if defined(BOOST_SPIRIT_DEBUG)
  135. token(id_type id, std::size_t, Iterator const& first
  136. , Iterator const& last)
  137. : matched_(first, last)
  138. , id_(id) {}
  139. #else
  140. token(id_type id, std::size_t, Iterator const&, Iterator const&)
  141. : id_(id) {}
  142. #endif
  143. // this default conversion operator is needed to allow the direct
  144. // usage of tokens in conjunction with the primitive parsers defined
  145. // in Qi
  146. operator id_type() const { return id_type(uid_type(id_)); }
  147. // Retrieve or set the token id of this token instance.
  148. id_type id() const { return id_type(uid_type(id_)); }
  149. void id(id_type newid) { id_ = uid_type(newid); }
  150. std::size_t state() const { return 0; } // always '0' (INITIAL state)
  151. bool is_valid() const
  152. {
  153. return 0 != id_ && boost::lexer::npos != id_;
  154. }
  155. #if defined(BOOST_SPIRIT_DEBUG)
  156. #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  157. // workaround for MSVC10 which has problems copying a default
  158. // constructed iterator_range
  159. token& operator= (token const& rhs)
  160. {
  161. if (this != &rhs)
  162. {
  163. id_ = rhs.id_;
  164. if (is_valid())
  165. matched_ = rhs.matched_;
  166. }
  167. return *this;
  168. }
  169. #endif
  170. std::pair<Iterator, Iterator> matched_;
  171. #endif
  172. protected:
  173. std::size_t id_; // token id, 0 if nothing has been matched
  174. };
  175. #if defined(BOOST_SPIRIT_DEBUG)
  176. template <typename Char, typename Traits, typename Iterator
  177. , typename AttributeTypes, typename HasState, typename Idtype>
  178. inline std::basic_ostream<Char, Traits>&
  179. operator<< (std::basic_ostream<Char, Traits>& os
  180. , token<Iterator, AttributeTypes, HasState, Idtype> const& t)
  181. {
  182. if (t.is_valid()) {
  183. Iterator end = t.matched_.second;
  184. for (Iterator it = t.matched_.first; it != end; ++it)
  185. os << *it;
  186. }
  187. else {
  188. os << "<invalid token>";
  189. }
  190. return os;
  191. }
  192. #endif
  193. ///////////////////////////////////////////////////////////////////////////
  194. // This specialization of the token type doesn't contain any item data but
  195. // supports working with lexer states.
  196. ///////////////////////////////////////////////////////////////////////////
  197. template <typename Iterator, typename Idtype>
  198. struct token<Iterator, lex::omit, mpl::true_, Idtype>
  199. : token<Iterator, lex::omit, mpl::false_, Idtype>
  200. {
  201. private:
  202. typedef token<Iterator, lex::omit, mpl::false_, Idtype> base_type;
  203. public:
  204. typedef typename base_type::id_type id_type;
  205. typedef Iterator iterator_type;
  206. typedef mpl::true_ has_state;
  207. typedef unused_type token_value_type;
  208. // default constructed tokens correspond to EOI tokens
  209. token() : state_(boost::lexer::npos) {}
  210. // construct an invalid token
  211. explicit token(int) : base_type(0), state_(boost::lexer::npos) {}
  212. token(id_type id, std::size_t state)
  213. : base_type(id, boost::lexer::npos), state_(state) {}
  214. token(id_type id, std::size_t state, token_value_type)
  215. : base_type(id, boost::lexer::npos, unused)
  216. , state_(state) {}
  217. token(id_type id, std::size_t state
  218. , Iterator const& first, Iterator const& last)
  219. : base_type(id, boost::lexer::npos, first, last)
  220. , state_(state) {}
  221. std::size_t state() const { return state_; }
  222. #if defined(BOOST_SPIRIT_DEBUG) && BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  223. // workaround for MSVC10 which has problems copying a default
  224. // constructed iterator_range
  225. token& operator= (token const& rhs)
  226. {
  227. if (this != &rhs)
  228. {
  229. this->base_type::operator=(static_cast<base_type const&>(rhs));
  230. state_ = rhs.state_;
  231. }
  232. return *this;
  233. }
  234. #endif
  235. protected:
  236. std::size_t state_; // lexer state this token was matched in
  237. };
  238. ///////////////////////////////////////////////////////////////////////////
  239. // The generic version of the token type derives from the
  240. // specialization above and adds a single data member holding the item
  241. // data carried by the token instance.
  242. ///////////////////////////////////////////////////////////////////////////
  243. namespace detail
  244. {
  245. ///////////////////////////////////////////////////////////////////////
  246. // Meta-function to calculate the type of the variant data item to be
  247. // stored with each token instance.
  248. //
  249. // Note: The iterator pair needs to be the first type in the list of
  250. // types supported by the generated variant type (this is being
  251. // used to identify whether the stored data item in a particular
  252. // token instance needs to be converted from the pair of
  253. // iterators (see the first of the assign_to_attribute_from_value
  254. // specializations below).
  255. ///////////////////////////////////////////////////////////////////////
  256. template <typename IteratorPair, typename AttributeTypes>
  257. struct token_value_typesequence
  258. {
  259. typedef typename mpl::insert<
  260. AttributeTypes
  261. , typename mpl::begin<AttributeTypes>::type
  262. , IteratorPair
  263. >::type sequence_type;
  264. typedef typename make_variant_over<sequence_type>::type type;
  265. };
  266. ///////////////////////////////////////////////////////////////////////
  267. // The type of the data item stored with a token instance is defined
  268. // by the template parameter 'AttributeTypes' and may be:
  269. //
  270. // lex::omit: no data item is stored with the token
  271. // instance (this is handled by the
  272. // specializations of the token class
  273. // below)
  274. // mpl::vector0<>: each token instance stores a pair of
  275. // iterators pointing to the matched input
  276. // sequence
  277. // mpl::vector<...>: each token instance stores a variant being
  278. // able to store the pair of iterators pointing
  279. // to the matched input sequence, or any of the
  280. // types a specified in the mpl::vector<>
  281. //
  282. // All this is done to ensure the token type is as small (in terms
  283. // of its byte-size) as possible.
  284. ///////////////////////////////////////////////////////////////////////
  285. template <typename IteratorPair, typename AttributeTypes>
  286. struct token_value_type
  287. : mpl::eval_if<
  288. mpl::or_<
  289. is_same<AttributeTypes, mpl::vector0<> >
  290. , is_same<AttributeTypes, mpl::vector<> > >
  291. , mpl::identity<IteratorPair>
  292. , token_value_typesequence<IteratorPair, AttributeTypes> >
  293. {};
  294. }
  295. template <typename Iterator, typename AttributeTypes, typename HasState
  296. , typename Idtype>
  297. struct token : token<Iterator, lex::omit, HasState, Idtype>
  298. {
  299. private: // precondition assertions
  300. BOOST_STATIC_ASSERT((mpl::is_sequence<AttributeTypes>::value ||
  301. is_same<AttributeTypes, lex::omit>::value));
  302. typedef token<Iterator, lex::omit, HasState, Idtype> base_type;
  303. protected:
  304. // If no additional token value types are given, the token will
  305. // hold the plain pair of iterators pointing to the matched range
  306. // in the underlying input sequence. Otherwise the token value is
  307. // stored as a variant and will again hold the pair of iterators but
  308. // is able to hold any of the given data types as well. The conversion
  309. // from the iterator pair to the required data type is done when it is
  310. // accessed for the first time.
  311. typedef iterator_range<Iterator> iterpair_type;
  312. public:
  313. typedef typename base_type::id_type id_type;
  314. typedef typename detail::token_value_type<
  315. iterpair_type, AttributeTypes
  316. >::type token_value_type;
  317. typedef Iterator iterator_type;
  318. // default constructed tokens correspond to EOI tokens
  319. token() : value_(iterpair_type(iterator_type(), iterator_type())) {}
  320. // construct an invalid token
  321. explicit token(int)
  322. : base_type(0)
  323. , value_(iterpair_type(iterator_type(), iterator_type())) {}
  324. token(id_type id, std::size_t state, token_value_type const& value)
  325. : base_type(id, state, value)
  326. , value_(value) {}
  327. token(id_type id, std::size_t state, Iterator const& first
  328. , Iterator const& last)
  329. : base_type(id, state, first, last)
  330. , value_(iterpair_type(first, last)) {}
  331. token_value_type& value() { return value_; }
  332. token_value_type const& value() const { return value_; }
  333. #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  334. // workaround for MSVC10 which has problems copying a default
  335. // constructed iterator_range
  336. token& operator= (token const& rhs)
  337. {
  338. if (this != &rhs)
  339. {
  340. this->base_type::operator=(static_cast<base_type const&>(rhs));
  341. if (this->is_valid())
  342. value_ = rhs.value_;
  343. }
  344. return *this;
  345. }
  346. #endif
  347. protected:
  348. token_value_type value_; // token value, by default a pair of iterators
  349. };
  350. ///////////////////////////////////////////////////////////////////////////
  351. // tokens are considered equal, if their id's match (these are unique)
  352. template <typename Iterator, typename AttributeTypes, typename HasState
  353. , typename Idtype>
  354. inline bool
  355. operator== (token<Iterator, AttributeTypes, HasState, Idtype> const& lhs,
  356. token<Iterator, AttributeTypes, HasState, Idtype> const& rhs)
  357. {
  358. return lhs.id() == rhs.id();
  359. }
  360. ///////////////////////////////////////////////////////////////////////////
  361. // This overload is needed by the multi_pass/functor_input_policy to
  362. // validate a token instance. It has to be defined in the same namespace
  363. // as the token class itself to allow ADL to find it.
  364. ///////////////////////////////////////////////////////////////////////////
  365. template <typename Iterator, typename AttributeTypes, typename HasState
  366. , typename Idtype>
  367. inline bool
  368. token_is_valid(token<Iterator, AttributeTypes, HasState, Idtype> const& t)
  369. {
  370. return t.is_valid();
  371. }
  372. }}}}
  373. namespace boost { namespace spirit { namespace traits
  374. {
  375. ///////////////////////////////////////////////////////////////////////////
  376. // We have to provide specializations for the customization point
  377. // assign_to_attribute_from_value allowing to extract the needed value
  378. // from the token.
  379. ///////////////////////////////////////////////////////////////////////////
  380. // This is called from the parse function of token_def if the token_def
  381. // has been defined to carry a special attribute type
  382. template <typename Attribute, typename Iterator, typename AttributeTypes
  383. , typename HasState, typename Idtype>
  384. struct assign_to_attribute_from_value<Attribute
  385. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  386. {
  387. static void
  388. call(lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> const& t
  389. , Attribute& attr)
  390. {
  391. // The goal of this function is to avoid the conversion of the pair of
  392. // iterators (to the matched character sequence) into the token value
  393. // of the required type being done more than once. For this purpose it
  394. // checks whether the stored value type is still the default one (pair
  395. // of iterators) and if yes, replaces the pair of iterators with the
  396. // converted value to be returned from subsequent calls.
  397. if (0 == t.value().which()) {
  398. // first access to the token value
  399. typedef iterator_range<Iterator> iterpair_type;
  400. iterpair_type const& ip = boost::get<iterpair_type>(t.value());
  401. // Interestingly enough we use the assign_to() framework defined in
  402. // Spirit.Qi allowing to convert the pair of iterators to almost any
  403. // required type (assign_to(), if available, uses the standard Spirit
  404. // parsers to do the conversion).
  405. spirit::traits::assign_to(ip.begin(), ip.end(), attr);
  406. // If you get an error during the compilation of the following
  407. // assignment expression, you probably forgot to list one or more
  408. // types used as token value types (in your token_def<...>
  409. // definitions) in your definition of the token class. I.e. any token
  410. // value type used for a token_def<...> definition has to be listed
  411. // during the declaration of the token type to use. For instance let's
  412. // assume we have two token_def's:
  413. //
  414. // token_def<int> number; number = "...";
  415. // token_def<std::string> identifier; identifier = "...";
  416. //
  417. // Then you'll have to use the following token type definition
  418. // (assuming you are using the token class):
  419. //
  420. // typedef mpl::vector<int, std::string> token_values;
  421. // typedef token<base_iter_type, token_values> token_type;
  422. //
  423. // where: base_iter_type is the iterator type used to expose the
  424. // underlying input stream.
  425. //
  426. // This token_type has to be used as the second template parameter
  427. // to the lexer class:
  428. //
  429. // typedef lexer<base_iter_type, token_type> lexer_type;
  430. //
  431. // again, assuming you're using the lexer<> template for your
  432. // tokenization.
  433. typedef lex::lexertl::token<
  434. Iterator, AttributeTypes, HasState, Idtype> token_type;
  435. spirit::traits::assign_to(
  436. attr, const_cast<token_type&>(t).value()); // re-assign value
  437. }
  438. else {
  439. // reuse the already assigned value
  440. spirit::traits::assign_to(boost::get<Attribute>(t.value()), attr);
  441. }
  442. }
  443. };
  444. template <typename Attribute, typename Iterator, typename AttributeTypes
  445. , typename HasState, typename Idtype>
  446. struct assign_to_container_from_value<Attribute
  447. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  448. : assign_to_attribute_from_value<Attribute
  449. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  450. {};
  451. template <typename Iterator, typename AttributeTypes
  452. , typename HasState, typename Idtype>
  453. struct assign_to_container_from_value<utree
  454. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  455. : assign_to_attribute_from_value<utree
  456. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  457. {};
  458. template <typename Iterator>
  459. struct assign_to_container_from_value<
  460. iterator_range<Iterator>, iterator_range<Iterator> >
  461. {
  462. static void
  463. call(iterator_range<Iterator> const& val, iterator_range<Iterator>& attr)
  464. {
  465. attr = val;
  466. }
  467. };
  468. // These are called from the parse function of token_def if the token type
  469. // has no special attribute type assigned
  470. template <typename Attribute, typename Iterator, typename HasState
  471. , typename Idtype>
  472. struct assign_to_attribute_from_value<Attribute
  473. , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> >
  474. {
  475. static void
  476. call(lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> const& t
  477. , Attribute& attr)
  478. {
  479. // The default type returned by the token_def parser component (if
  480. // it has no token value type assigned) is the pair of iterators
  481. // to the matched character sequence.
  482. spirit::traits::assign_to(t.value().begin(), t.value().end(), attr);
  483. }
  484. };
  485. // template <typename Attribute, typename Iterator, typename HasState
  486. // , typename Idtype>
  487. // struct assign_to_container_from_value<Attribute
  488. // , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> >
  489. // : assign_to_attribute_from_value<Attribute
  490. // , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> >
  491. // {};
  492. // same as above but using mpl::vector<> instead of mpl::vector0<>
  493. template <typename Attribute, typename Iterator, typename HasState
  494. , typename Idtype>
  495. struct assign_to_attribute_from_value<Attribute
  496. , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> >
  497. {
  498. static void
  499. call(lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> const& t
  500. , Attribute& attr)
  501. {
  502. // The default type returned by the token_def parser component (if
  503. // it has no token value type assigned) is the pair of iterators
  504. // to the matched character sequence.
  505. spirit::traits::assign_to(t.value().begin(), t.value().end(), attr);
  506. }
  507. };
  508. // template <typename Attribute, typename Iterator, typename HasState
  509. // , typename Idtype>
  510. // struct assign_to_container_from_value<Attribute
  511. // , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> >
  512. // : assign_to_attribute_from_value<Attribute
  513. // , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> >
  514. // {};
  515. // This is called from the parse function of token_def if the token type
  516. // has been explicitly omitted (i.e. no attribute value is used), which
  517. // essentially means that every attribute gets initialized using default
  518. // constructed values.
  519. template <typename Attribute, typename Iterator, typename HasState
  520. , typename Idtype>
  521. struct assign_to_attribute_from_value<Attribute
  522. , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> >
  523. {
  524. static void
  525. call(lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> const&
  526. , Attribute&)
  527. {
  528. // do nothing
  529. }
  530. };
  531. template <typename Attribute, typename Iterator, typename HasState
  532. , typename Idtype>
  533. struct assign_to_container_from_value<Attribute
  534. , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> >
  535. : assign_to_attribute_from_value<Attribute
  536. , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> >
  537. {};
  538. // This is called from the parse function of lexer_def_
  539. template <typename Iterator, typename AttributeTypes, typename HasState
  540. , typename Idtype_, typename Idtype>
  541. struct assign_to_attribute_from_value<
  542. fusion::vector2<Idtype_, iterator_range<Iterator> >
  543. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  544. {
  545. static void
  546. call(lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> const& t
  547. , fusion::vector2<Idtype_, iterator_range<Iterator> >& attr)
  548. {
  549. // The type returned by the lexer_def_ parser components is a
  550. // fusion::vector containing the token id of the matched token
  551. // and the pair of iterators to the matched character sequence.
  552. typedef iterator_range<Iterator> iterpair_type;
  553. typedef fusion::vector2<Idtype_, iterator_range<Iterator> >
  554. attribute_type;
  555. iterpair_type const& ip = boost::get<iterpair_type>(t.value());
  556. attr = attribute_type(t.id(), ip);
  557. }
  558. };
  559. template <typename Iterator, typename AttributeTypes, typename HasState
  560. , typename Idtype_, typename Idtype>
  561. struct assign_to_container_from_value<
  562. fusion::vector2<Idtype_, iterator_range<Iterator> >
  563. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  564. : assign_to_attribute_from_value<
  565. fusion::vector2<Idtype_, iterator_range<Iterator> >
  566. , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
  567. {};
  568. ///////////////////////////////////////////////////////////////////////////
  569. // Overload debug output for a single token, this integrates lexer tokens
  570. // with Qi's simple_trace debug facilities
  571. template <typename Iterator, typename Attribute, typename HasState
  572. , typename Idtype>
  573. struct token_printer_debug<
  574. lex::lexertl::token<Iterator, Attribute, HasState, Idtype> >
  575. {
  576. typedef lex::lexertl::token<Iterator, Attribute, HasState, Idtype> token_type;
  577. template <typename Out>
  578. static void print(Out& out, token_type const& val)
  579. {
  580. out << '[';
  581. spirit::traits::print_token(out, val.value());
  582. out << ']';
  583. }
  584. };
  585. }}}
  586. #endif