token.hpp 27 KB

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