9
3

position_token.hpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  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_POSITION_TOKEN_MAY_13_2011_0846PM)
  6. #define BOOST_SPIRIT_LEX_POSITION_TOKEN_MAY_13_2011_0846PM
  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/vector.hpp>
  25. #include <boost/mpl/bool.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/is_same.hpp>
  33. #include <boost/range/iterator_range.hpp>
  34. #include <boost/static_assert.hpp>
  35. #if defined(BOOST_SPIRIT_DEBUG)
  36. #include <iosfwd>
  37. #endif
  38. namespace boost { namespace spirit { namespace lex { namespace lexertl
  39. {
  40. ///////////////////////////////////////////////////////////////////////////
  41. //
  42. // The position_token is the type of the objects returned by the
  43. // iterator if it has been specified while instantiating the lexer object.
  44. //
  45. // template parameters:
  46. // Iterator The type of the iterator used to access the
  47. // underlying character stream.
  48. // AttributeTypes A mpl sequence containing the types of all
  49. // required different token values to be supported
  50. // by this token type.
  51. // HasState A mpl::bool_ indicating, whether this token type
  52. // should support lexer states.
  53. // Idtype The type to use for the token id (defaults to
  54. // std::size_t).
  55. //
  56. // It is possible to use other token types with the spirit::lex
  57. // framework as well. If you plan to use a different type as your token
  58. // type, you'll need to expose the following things from your token type
  59. // to make it compatible with spirit::lex:
  60. //
  61. // typedefs
  62. // iterator_type The type of the iterator used to access the
  63. // underlying character stream.
  64. //
  65. // id_type The type of the token id used.
  66. //
  67. // methods
  68. // default constructor
  69. // This should initialize the token as an end of
  70. // input token.
  71. // constructors The prototype of the other required
  72. // constructors should be:
  73. //
  74. // token(int)
  75. // This constructor should initialize the token as
  76. // an invalid token (not carrying any specific
  77. // values)
  78. //
  79. // where: the int is used as a tag only and its value is
  80. // ignored
  81. //
  82. // and:
  83. //
  84. // token(Idtype id, std::size_t state,
  85. // iterator_type first, iterator_type last);
  86. //
  87. // where: id: token id
  88. // state: lexer state this token was matched in
  89. // first, last: pair of iterators marking the matched
  90. // range in the underlying input stream
  91. //
  92. // accessors
  93. // id() return the token id of the matched input sequence
  94. // id(newid) set the token id of the token instance
  95. //
  96. // state() return the lexer state this token was matched in
  97. //
  98. // value() return the token value
  99. //
  100. // Additionally, you will have to implement a couple of helper functions
  101. // in the same namespace as the token type: a comparison operator==() to
  102. // compare your token instances, a token_is_valid() function and different
  103. // specializations of the Spirit customization point
  104. // assign_to_attribute_from_value as shown below.
  105. //
  106. ///////////////////////////////////////////////////////////////////////////
  107. template <typename Iterator = char const*
  108. , typename AttributeTypes = mpl::vector0<>
  109. , typename HasState = mpl::true_
  110. , typename Idtype = std::size_t>
  111. struct position_token;
  112. ///////////////////////////////////////////////////////////////////////////
  113. // This specialization of the token type doesn't contain any item data and
  114. // doesn't support working with lexer states. Although, like all other
  115. // variants of position_token, it carries a pair of iterators marking the
  116. // begin and the end of the matched character sequence.
  117. ///////////////////////////////////////////////////////////////////////////
  118. template <typename Iterator, typename Idtype>
  119. struct position_token<Iterator, lex::omit, mpl::false_, Idtype>
  120. {
  121. typedef Iterator iterator_type;
  122. typedef iterator_range<iterator_type> iterpair_type;
  123. typedef mpl::false_ has_state;
  124. typedef Idtype id_type;
  125. typedef unused_type token_value_type;
  126. // default constructed tokens correspond to EOI tokens
  127. position_token()
  128. : id_(id_type(boost::lexer::npos)) {}
  129. // construct an invalid token
  130. explicit position_token(int)
  131. : id_(id_type(0)) {}
  132. position_token(id_type id, std::size_t)
  133. : id_(id) {}
  134. position_token(id_type id, std::size_t, token_value_type)
  135. : id_(id) {}
  136. position_token(id_type id, std::size_t, Iterator const& first
  137. , Iterator const& last)
  138. : id_(id), matched_(first, last) {}
  139. // this default conversion operator is needed to allow the direct
  140. // usage of tokens in conjunction with the primitive parsers defined
  141. // in Qi
  142. operator id_type() const { return id_; }
  143. // Retrieve or set the token id of this token instance.
  144. id_type id() const { return id_; }
  145. void id(id_type newid) { id_ = newid; }
  146. std::size_t state() const { return 0; } // always '0' (INITIAL state)
  147. bool is_valid() const
  148. {
  149. return 0 != id_ && id_type(boost::lexer::npos) != id_;
  150. }
  151. // access the stored iterator range of the matched input sequence
  152. iterator_type begin() const { return matched_.begin(); }
  153. iterator_type end() const { return matched_.end(); }
  154. iterpair_type& matched() { return matched_; }
  155. iterpair_type const& matched() const { return matched_; }
  156. token_value_type& value() { static token_value_type u; return u; }
  157. token_value_type const& value() const { return unused; }
  158. #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  159. // workaround for MSVC10 which has problems copying a default
  160. // constructed iterator_range
  161. position_token& operator= (position_token const& rhs)
  162. {
  163. if (this != &rhs)
  164. {
  165. id_ = rhs.id_;
  166. if (is_valid())
  167. matched_ = rhs.matched_;
  168. }
  169. return *this;
  170. }
  171. #endif
  172. protected:
  173. id_type id_; // token id, 0 if nothing has been matched
  174. iterpair_type matched_; // matched input sequence
  175. };
  176. #if defined(BOOST_SPIRIT_DEBUG)
  177. template <typename Char, typename Traits, typename Iterator
  178. , typename AttributeTypes, typename HasState, typename Idtype>
  179. inline std::basic_ostream<Char, Traits>&
  180. operator<< (std::basic_ostream<Char, Traits>& os
  181. , position_token<Iterator, AttributeTypes, HasState, Idtype> const& t)
  182. {
  183. if (t.is_valid()) {
  184. Iterator end = t.end();
  185. for (Iterator it = t.begin(); it != end; ++it)
  186. os << *it;
  187. }
  188. else {
  189. os << "<invalid token>";
  190. }
  191. return os;
  192. }
  193. #endif
  194. ///////////////////////////////////////////////////////////////////////////
  195. // This specialization of the token type doesn't contain any item data but
  196. // supports working with lexer states.
  197. ///////////////////////////////////////////////////////////////////////////
  198. template <typename Iterator, typename Idtype>
  199. struct position_token<Iterator, lex::omit, mpl::true_, Idtype>
  200. : position_token<Iterator, lex::omit, mpl::false_, Idtype>
  201. {
  202. private:
  203. typedef position_token<Iterator, lex::omit, mpl::false_, Idtype>
  204. base_type;
  205. public:
  206. typedef typename base_type::id_type id_type;
  207. typedef Iterator iterator_type;
  208. typedef mpl::true_ has_state;
  209. typedef unused_type token_value_type;
  210. // default constructed tokens correspond to EOI tokens
  211. position_token() : state_(boost::lexer::npos) {}
  212. // construct an invalid token
  213. explicit position_token(int)
  214. : base_type(0), state_(boost::lexer::npos) {}
  215. position_token(id_type id, std::size_t state)
  216. : base_type(id, boost::lexer::npos), state_(state) {}
  217. position_token(id_type id, std::size_t state, token_value_type)
  218. : base_type(id, boost::lexer::npos, unused)
  219. , state_(state) {}
  220. position_token(id_type id, std::size_t state
  221. , Iterator const& first, Iterator const& last)
  222. : base_type(id, boost::lexer::npos, first, last)
  223. , state_(state) {}
  224. std::size_t state() const { return state_; }
  225. #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  226. // workaround for MSVC10 which has problems copying a default
  227. // constructed iterator_range
  228. position_token& operator= (position_token const& rhs)
  229. {
  230. if (this != &rhs)
  231. {
  232. this->base_type::operator=(static_cast<base_type const&>(rhs));
  233. state_ = rhs.state_;
  234. }
  235. return *this;
  236. }
  237. #endif
  238. protected:
  239. std::size_t state_; // lexer state this token was matched in
  240. };
  241. ///////////////////////////////////////////////////////////////////////////
  242. // These specializations for an empty attribute list cause all token
  243. // instances to expose as it attribute the iterator_range pointing to the
  244. // matched input sequence.
  245. ///////////////////////////////////////////////////////////////////////////
  246. template <typename Iterator, typename HasState, typename Idtype>
  247. struct position_token<Iterator, mpl::vector<>, HasState, Idtype>
  248. : position_token<Iterator, lex::omit, HasState, Idtype>
  249. {
  250. private:
  251. typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
  252. public:
  253. typedef typename base_type::id_type id_type;
  254. typedef typename base_type::iterator_type iterator_type;
  255. typedef typename base_type::iterpair_type iterpair_type;
  256. typedef HasState has_state;
  257. typedef iterpair_type token_value_type;
  258. // default constructed tokens correspond to EOI tokens
  259. position_token() {}
  260. // construct an invalid token
  261. explicit position_token(int)
  262. : base_type(0) {}
  263. position_token(id_type id, std::size_t state)
  264. : base_type(id, state) {}
  265. position_token(id_type id, std::size_t state, token_value_type)
  266. : base_type(id, state, unused) {}
  267. position_token(id_type id, std::size_t state
  268. , Iterator const& first, Iterator const& last)
  269. : base_type(id, state, first, last) {}
  270. token_value_type& value() { return this->base_type::matched(); }
  271. token_value_type const& value() const { return this->base_type::matched(); }
  272. };
  273. template <typename Iterator, typename HasState, typename Idtype>
  274. struct position_token<Iterator, mpl::vector0<>, HasState, Idtype>
  275. : position_token<Iterator, lex::omit, HasState, Idtype>
  276. {
  277. private:
  278. typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
  279. public:
  280. typedef typename base_type::id_type id_type;
  281. typedef typename base_type::iterator_type iterator_type;
  282. typedef typename base_type::iterpair_type iterpair_type;
  283. typedef HasState has_state;
  284. typedef iterpair_type token_value_type;
  285. // default constructed tokens correspond to EOI tokens
  286. position_token() {}
  287. // construct an invalid token
  288. explicit position_token(int)
  289. : base_type(0) {}
  290. position_token(id_type id, std::size_t state)
  291. : base_type(id, state) {}
  292. position_token(id_type id, std::size_t state, token_value_type)
  293. : base_type(id, state, unused) {}
  294. position_token(id_type id, std::size_t state
  295. , Iterator const& first, Iterator const& last)
  296. : base_type(id, state, first, last) {}
  297. token_value_type& value() { return this->base_type::matched(); }
  298. token_value_type const& value() const { return this->base_type::matched(); }
  299. };
  300. ///////////////////////////////////////////////////////////////////////////
  301. // These specializations for an attribute list of length one cause all token
  302. // instances to expose the specified type as its attribute.
  303. ///////////////////////////////////////////////////////////////////////////
  304. template <typename Iterator, typename Attribute, typename HasState
  305. , typename Idtype>
  306. struct position_token<Iterator, mpl::vector<Attribute>, HasState, Idtype>
  307. : position_token<Iterator, lex::omit, HasState, Idtype>
  308. {
  309. private:
  310. typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
  311. public:
  312. typedef typename base_type::id_type id_type;
  313. typedef typename base_type::iterator_type iterator_type;
  314. typedef typename base_type::iterpair_type iterpair_type;
  315. typedef HasState has_state;
  316. typedef boost::optional<Attribute> token_value_type;
  317. // default constructed tokens correspond to EOI tokens
  318. position_token() {}
  319. // construct an invalid token
  320. explicit position_token(int)
  321. : base_type(0) {}
  322. position_token(id_type id, std::size_t state)
  323. : base_type(id, state) {}
  324. position_token(id_type id, std::size_t state, token_value_type const& v)
  325. : base_type(id, state, unused), value_(v) {}
  326. position_token(id_type id, std::size_t state
  327. , Iterator const& first, Iterator const& last)
  328. : base_type(id, state, first, last) {}
  329. token_value_type& value() { return value_; }
  330. token_value_type const& value() const { return value_; }
  331. bool has_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. position_token& operator= (position_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
  348. };
  349. template <typename Iterator, typename Attribute, typename HasState
  350. , typename Idtype>
  351. struct position_token<Iterator, mpl::vector1<Attribute>, HasState, Idtype>
  352. : position_token<Iterator, lex::omit, HasState, Idtype>
  353. {
  354. private:
  355. typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
  356. public:
  357. typedef typename base_type::id_type id_type;
  358. typedef typename base_type::iterator_type iterator_type;
  359. typedef typename base_type::iterpair_type iterpair_type;
  360. typedef HasState has_state;
  361. typedef boost::optional<Attribute> token_value_type;
  362. // default constructed tokens correspond to EOI tokens
  363. position_token() {}
  364. // construct an invalid token
  365. explicit position_token(int)
  366. : base_type(0) {}
  367. position_token(id_type id, std::size_t state)
  368. : base_type(id, state) {}
  369. position_token(id_type id, std::size_t state, token_value_type const& v)
  370. : base_type(id, state, unused), value_(v) {}
  371. position_token(id_type id, std::size_t state
  372. , Iterator const& first, Iterator const& last)
  373. : base_type(id, state, first, last) {}
  374. token_value_type& value() { return value_; }
  375. token_value_type const& value() const { return value_; }
  376. bool has_value() const { return value_; }
  377. #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  378. // workaround for MSVC10 which has problems copying a default
  379. // constructed iterator_range
  380. position_token& operator= (position_token const& rhs)
  381. {
  382. if (this != &rhs)
  383. {
  384. this->base_type::operator=(static_cast<base_type const&>(rhs));
  385. if (this->is_valid())
  386. value_ = rhs.value_;
  387. }
  388. return *this;
  389. }
  390. #endif
  391. protected:
  392. token_value_type value_; // token value
  393. };
  394. ///////////////////////////////////////////////////////////////////////////
  395. // The generic version of the position_token type derives from the
  396. // specialization above and adds a single data member holding the item
  397. // data carried by the token instance.
  398. ///////////////////////////////////////////////////////////////////////////
  399. namespace detail
  400. {
  401. ///////////////////////////////////////////////////////////////////////
  402. // Meta-function to calculate the type of the variant data item to be
  403. // stored with each token instance.
  404. //
  405. // Note: The iterator pair needs to be the first type in the list of
  406. // types supported by the generated variant type (this is being
  407. // used to identify whether the stored data item in a particular
  408. // token instance needs to be converted from the pair of
  409. // iterators (see the first of the assign_to_attribute_from_value
  410. // specializations below).
  411. ///////////////////////////////////////////////////////////////////////
  412. template <typename IteratorPair, typename AttributeTypes>
  413. struct position_token_value_typesequence
  414. {
  415. typedef typename mpl::insert<
  416. AttributeTypes
  417. , typename mpl::begin<AttributeTypes>::type
  418. , IteratorPair
  419. >::type sequence_type;
  420. typedef typename make_variant_over<sequence_type>::type type;
  421. };
  422. ///////////////////////////////////////////////////////////////////////
  423. // The type of the data item stored with a token instance is defined
  424. // by the template parameter 'AttributeTypes' and may be:
  425. //
  426. // lex::omit: no data item is stored with the token
  427. // instance (this is handled by the
  428. // specializations of the token class
  429. // below)
  430. // mpl::vector0<>: each token instance stores a pair of
  431. // iterators pointing to the matched input
  432. // sequence
  433. // mpl::vector<...>: each token instance stores a variant being
  434. // able to store the pair of iterators pointing
  435. // to the matched input sequence, or any of the
  436. // types a specified in the mpl::vector<>
  437. //
  438. // All this is done to ensure the token type is as small (in terms
  439. // of its byte-size) as possible.
  440. ///////////////////////////////////////////////////////////////////////
  441. template <typename IteratorPair, typename AttributeTypes>
  442. struct position_token_value
  443. : mpl::eval_if<
  444. mpl::or_<
  445. is_same<AttributeTypes, mpl::vector0<> >
  446. , is_same<AttributeTypes, mpl::vector<> > >
  447. , mpl::identity<IteratorPair>
  448. , position_token_value_typesequence<IteratorPair, AttributeTypes> >
  449. {};
  450. }
  451. template <typename Iterator, typename AttributeTypes, typename HasState
  452. , typename Idtype>
  453. struct position_token
  454. : position_token<Iterator, lex::omit, HasState, Idtype>
  455. {
  456. private: // precondition assertions
  457. BOOST_STATIC_ASSERT((mpl::is_sequence<AttributeTypes>::value ||
  458. is_same<AttributeTypes, lex::omit>::value));
  459. typedef position_token<Iterator, lex::omit, HasState, Idtype>
  460. base_type;
  461. protected:
  462. // If no additional token value types are given, the token will
  463. // hold no token value at all as the base class already has the
  464. // iterator pair of the matched range in the underlying input sequence.
  465. // Otherwise the token value is stored as a variant and will
  466. // initially hold an unused_type but is able to hold any of
  467. // the given data types as well. The conversion from the iterator pair
  468. // to the required data type is done when it is accessed for the first
  469. // time.
  470. typedef iterator_range<Iterator> iterpair_type;
  471. public:
  472. typedef typename base_type::id_type id_type;
  473. typedef typename detail::position_token_value<
  474. iterpair_type, AttributeTypes>::type token_value_type;
  475. typedef Iterator iterator_type;
  476. // default constructed tokens correspond to EOI tokens
  477. position_token() {}
  478. // construct an invalid token
  479. explicit position_token(int)
  480. : base_type(0) {}
  481. position_token(id_type id, std::size_t state, token_value_type const& value)
  482. : base_type(id, state, value), value_(value) {}
  483. position_token(id_type id, std::size_t state, Iterator const& first
  484. , Iterator const& last)
  485. : base_type(id, state, first, last)
  486. , value_(iterpair_type(first, last))
  487. {}
  488. token_value_type& value() { return value_; }
  489. token_value_type const& value() const { return value_; }
  490. #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
  491. // workaround for MSVC10 which has problems copying a default
  492. // constructed iterator_range
  493. position_token& operator= (position_token const& rhs)
  494. {
  495. if (this != &rhs)
  496. {
  497. this->base_type::operator=(static_cast<base_type const&>(rhs));
  498. if (this->is_valid())
  499. value_ = rhs.value_;
  500. }
  501. return *this;
  502. }
  503. #endif
  504. protected:
  505. token_value_type value_; // token value, by default a pair of iterators
  506. };
  507. ///////////////////////////////////////////////////////////////////////////
  508. // tokens are considered equal, if their id's match (these are unique)
  509. template <typename Iterator, typename AttributeTypes, typename HasState
  510. , typename Idtype>
  511. inline bool
  512. operator== (position_token<Iterator, AttributeTypes, HasState, Idtype> const& lhs,
  513. position_token<Iterator, AttributeTypes, HasState, Idtype> const& rhs)
  514. {
  515. return lhs.id() == rhs.id();
  516. }
  517. ///////////////////////////////////////////////////////////////////////////
  518. // This overload is needed by the multi_pass/functor_input_policy to
  519. // validate a token instance. It has to be defined in the same namespace
  520. // as the token class itself to allow ADL to find it.
  521. ///////////////////////////////////////////////////////////////////////////
  522. template <typename Iterator, typename AttributeTypes, typename HasState
  523. , typename Idtype>
  524. inline bool
  525. token_is_valid(position_token<Iterator, AttributeTypes, HasState, Idtype> const& t)
  526. {
  527. return t.is_valid();
  528. }
  529. }}}}
  530. namespace boost { namespace spirit { namespace traits
  531. {
  532. ///////////////////////////////////////////////////////////////////////////
  533. // We have to provide specializations for the customization point
  534. // assign_to_attribute_from_value allowing to extract the needed value
  535. // from the token.
  536. ///////////////////////////////////////////////////////////////////////////
  537. // This is called from the parse function of token_def if the token_def
  538. // has been defined to carry a special attribute type
  539. template <typename Attribute, typename Iterator, typename AttributeTypes
  540. , typename HasState, typename Idtype>
  541. struct assign_to_attribute_from_value<Attribute
  542. , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
  543. {
  544. static void
  545. call(lex::lexertl::position_token<
  546. Iterator, AttributeTypes, HasState, Idtype> const& t
  547. , Attribute& attr)
  548. {
  549. // The goal of this function is to avoid the conversion of the pair of
  550. // iterators (to the matched character sequence) into the token value
  551. // of the required type being done more than once. For this purpose it
  552. // checks whether the stored value type is still the default one (pair
  553. // of iterators) and if yes, replaces the pair of iterators with the
  554. // converted value to be returned from subsequent calls.
  555. if (0 == t.value().which()) {
  556. // first access to the token value
  557. typedef iterator_range<Iterator> iterpair_type;
  558. iterpair_type const& ip = t.matched();
  559. // Interestingly enough we use the assign_to() framework defined in
  560. // Spirit.Qi allowing to convert the pair of iterators to almost any
  561. // required type (assign_to(), if available, uses the standard Spirit
  562. // parsers to do the conversion).
  563. spirit::traits::assign_to(ip.begin(), ip.end(), attr);
  564. // If you get an error during the compilation of the following
  565. // assignment expression, you probably forgot to list one or more
  566. // types used as token value types (in your token_def<...>
  567. // definitions) in your definition of the token class. I.e. any token
  568. // value type used for a token_def<...> definition has to be listed
  569. // during the declaration of the token type to use. For instance let's
  570. // assume we have two token_def's:
  571. //
  572. // token_def<int> number; number = "...";
  573. // token_def<std::string> identifier; identifier = "...";
  574. //
  575. // Then you'll have to use the following token type definition
  576. // (assuming you are using the token class):
  577. //
  578. // typedef mpl::vector<int, std::string> token_values;
  579. // typedef token<base_iter_type, token_values> token_type;
  580. //
  581. // where: base_iter_type is the iterator type used to expose the
  582. // underlying input stream.
  583. //
  584. // This token_type has to be used as the second template parameter
  585. // to the lexer class:
  586. //
  587. // typedef lexer<base_iter_type, token_type> lexer_type;
  588. //
  589. // again, assuming you're using the lexer<> template for your
  590. // tokenization.
  591. typedef lex::lexertl::position_token<
  592. Iterator, AttributeTypes, HasState, Idtype> token_type;
  593. spirit::traits::assign_to(
  594. attr, const_cast<token_type&>(t).value()); // re-assign value
  595. }
  596. else {
  597. // reuse the already assigned value
  598. spirit::traits::assign_to(get<Attribute>(t.value()), attr);
  599. }
  600. }
  601. };
  602. template <typename Attribute, typename Iterator, typename AttributeTypes
  603. , typename HasState, typename Idtype>
  604. struct assign_to_container_from_value<Attribute
  605. , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
  606. : assign_to_attribute_from_value<Attribute
  607. , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
  608. {};
  609. ///////////////////////////////////////////////////////////////////////////
  610. // These are called from the parse function of token_def if the token type
  611. // has no special attribute type assigned
  612. template <typename Attribute, typename Iterator, typename HasState
  613. , typename Idtype>
  614. struct assign_to_attribute_from_value<Attribute
  615. , lex::lexertl::position_token<Iterator, mpl::vector0<>, HasState, Idtype> >
  616. {
  617. static void
  618. call(lex::lexertl::position_token<
  619. Iterator, mpl::vector0<>, HasState, Idtype> const& t
  620. , Attribute& attr)
  621. {
  622. // The default type returned by the token_def parser component (if
  623. // it has no token value type assigned) is the pair of iterators
  624. // to the matched character sequence.
  625. spirit::traits::assign_to(t.begin(), t.end(), attr);
  626. }
  627. };
  628. // template <typename Attribute, typename Iterator, typename HasState
  629. // , typename Idtype>
  630. // struct assign_to_container_from_value<Attribute
  631. // , lex::lexertl::position_token<Iterator, mpl::vector0<>, HasState, Idtype> >
  632. // : assign_to_attribute_from_value<Attribute
  633. // , lex::lexertl::position_token<Iterator, mpl::vector0<>, HasState, Idtype> >
  634. // {};
  635. // same as above but using mpl::vector<> instead of mpl::vector0<>
  636. template <typename Attribute, typename Iterator, typename HasState
  637. , typename Idtype>
  638. struct assign_to_attribute_from_value<Attribute
  639. , lex::lexertl::position_token<Iterator, mpl::vector<>, HasState, Idtype> >
  640. {
  641. static void
  642. call(lex::lexertl::position_token<
  643. Iterator, mpl::vector<>, HasState, Idtype> const& t
  644. , Attribute& attr)
  645. {
  646. // The default type returned by the token_def parser component (if
  647. // it has no token value type assigned) is the pair of iterators
  648. // to the matched character sequence.
  649. spirit::traits::assign_to(t.begin(), t.end(), attr);
  650. }
  651. };
  652. // template <typename Attribute, typename Iterator, typename HasState
  653. // , typename Idtype>
  654. // struct assign_to_container_from_value<Attribute
  655. // , lex::lexertl::position_token<Iterator, mpl::vector<>, HasState, Idtype> >
  656. // : assign_to_attribute_from_value<Attribute
  657. // , lex::lexertl::position_token<Iterator, mpl::vector<>, HasState, Idtype> >
  658. // {};
  659. ///////////////////////////////////////////////////////////////////////////
  660. // These are called from the parse function of token_def if the token type
  661. // has no special attribute type assigned
  662. template <typename Attribute, typename Iterator, typename Attr
  663. , typename HasState, typename Idtype>
  664. struct assign_to_attribute_from_value<Attribute
  665. , lex::lexertl::position_token<Iterator, mpl::vector1<Attr>, HasState, Idtype> >
  666. {
  667. static void
  668. call(lex::lexertl::position_token<
  669. Iterator, mpl::vector1<Attr>, HasState, Idtype> const& t
  670. , Attribute& attr)
  671. {
  672. // The goal of this function is to avoid the conversion of the pair of
  673. // iterators (to the matched character sequence) into the token value
  674. // of the required type being done more than once.
  675. if (!t.has_value()) {
  676. // first access to the token value
  677. typedef iterator_range<Iterator> iterpair_type;
  678. iterpair_type const& ip = t.matched();
  679. // Interestingly enough we use the assign_to() framework defined in
  680. // Spirit.Qi allowing to convert the pair of iterators to almost any
  681. // required type (assign_to(), if available, uses the standard Spirit
  682. // parsers to do the conversion).
  683. spirit::traits::assign_to(ip.begin(), ip.end(), attr);
  684. // Re-assign the attribute to the stored value
  685. typedef lex::lexertl::position_token<
  686. Iterator, mpl::vector1<Attr>, HasState, Idtype> token_type;
  687. spirit::traits::assign_to(
  688. attr, const_cast<token_type&>(t).value());
  689. }
  690. else {
  691. // reuse the already assigned value
  692. spirit::traits::assign_to(t.value(), attr);
  693. }
  694. }
  695. };
  696. // template <typename Attribute, typename Iterator, typename Attr
  697. // , typename HasState, typename Idtype>
  698. // struct assign_to_container_from_value<Attribute
  699. // , lex::lexertl::position_token<Iterator, mpl::vector1<Attr>, HasState, Idtype> >
  700. // : assign_to_attribute_from_value<Attribute
  701. // , lex::lexertl::position_token<Iterator, mpl::vector1<Attr>, HasState, Idtype> >
  702. // {};
  703. // same as above but using mpl::vector<Attr> instead of mpl::vector1<Attr>
  704. template <typename Attribute, typename Iterator, typename Attr
  705. , typename HasState, typename Idtype>
  706. struct assign_to_attribute_from_value<Attribute
  707. , lex::lexertl::position_token<Iterator, mpl::vector<Attr>, HasState, Idtype> >
  708. {
  709. static void
  710. call(lex::lexertl::position_token<
  711. Iterator, mpl::vector<Attr>, HasState, Idtype> const& t
  712. , Attribute& attr)
  713. {
  714. // The goal of this function is to avoid the conversion of the pair of
  715. // iterators (to the matched character sequence) into the token value
  716. // of the required type being done more than once.
  717. if (!t.has_value()) {
  718. // first access to the token value
  719. typedef iterator_range<Iterator> iterpair_type;
  720. iterpair_type const& ip = t.matched();
  721. // Interestingly enough we use the assign_to() framework defined in
  722. // Spirit.Qi allowing to convert the pair of iterators to almost any
  723. // required type (assign_to(), if available, uses the standard Spirit
  724. // parsers to do the conversion).
  725. spirit::traits::assign_to(ip.begin(), ip.end(), attr);
  726. // Re-assign the attribute to the stored value
  727. typedef lex::lexertl::position_token<
  728. Iterator, mpl::vector<Attr>, HasState, Idtype> token_type;
  729. spirit::traits::assign_to(
  730. attr, const_cast<token_type&>(t).value());
  731. }
  732. else {
  733. // reuse the already assigned value
  734. spirit::traits::assign_to(t.value(), attr);
  735. }
  736. }
  737. };
  738. // template <typename Attribute, typename Iterator, typename Attr
  739. // , typename HasState, typename Idtype>
  740. // struct assign_to_container_from_value<Attribute
  741. // , lex::lexertl::position_token<Iterator, mpl::vector<Attr>, HasState, Idtype> >
  742. // : assign_to_attribute_from_value<Attribute
  743. // , lex::lexertl::position_token<Iterator, mpl::vector<Attr>, HasState, Idtype> >
  744. // {};
  745. // This is called from the parse function of token_def if the token type
  746. // has been explicitly omitted (i.e. no attribute value is used), which
  747. // essentially means that every attribute gets initialized using default
  748. // constructed values.
  749. template <typename Attribute, typename Iterator, typename HasState
  750. , typename Idtype>
  751. struct assign_to_attribute_from_value<Attribute
  752. , lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> >
  753. {
  754. static void
  755. call(lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> const& t
  756. , Attribute& attr)
  757. {
  758. // do nothing
  759. }
  760. };
  761. template <typename Attribute, typename Iterator, typename HasState
  762. , typename Idtype>
  763. struct assign_to_container_from_value<Attribute
  764. , lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> >
  765. : assign_to_attribute_from_value<Attribute
  766. , lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> >
  767. {};
  768. // This is called from the parse function of lexer_def_
  769. template <typename Iterator, typename AttributeTypes, typename HasState
  770. , typename Idtype_, typename Idtype>
  771. struct assign_to_attribute_from_value<
  772. fusion::vector2<Idtype_, iterator_range<Iterator> >
  773. , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
  774. {
  775. static void
  776. call(lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> const& t
  777. , fusion::vector2<Idtype_, iterator_range<Iterator> >& attr)
  778. {
  779. // The type returned by the lexer_def_ parser components is a
  780. // fusion::vector containing the token id of the matched token
  781. // and the pair of iterators to the matched character sequence.
  782. typedef iterator_range<Iterator> iterpair_type;
  783. typedef fusion::vector2<Idtype_, iterator_range<Iterator> >
  784. attribute_type;
  785. iterpair_type const& ip = t.matched();
  786. attr = attribute_type(t.id(), ip);
  787. }
  788. };
  789. template <typename Iterator, typename AttributeTypes, typename HasState
  790. , typename Idtype_, typename Idtype>
  791. struct assign_to_container_from_value<
  792. fusion::vector2<Idtype_, iterator_range<Iterator> >
  793. , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
  794. : assign_to_attribute_from_value<
  795. fusion::vector2<Idtype_, iterator_range<Iterator> >
  796. , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
  797. {};
  798. ///////////////////////////////////////////////////////////////////////////
  799. // Overload debug output for a single token, this integrates lexer tokens
  800. // with Qi's simple_trace debug facilities
  801. template <typename Iterator, typename Attribute, typename HasState
  802. , typename Idtype>
  803. struct token_printer_debug<
  804. lex::lexertl::position_token<Iterator, Attribute, HasState, Idtype> >
  805. {
  806. typedef lex::lexertl::position_token<Iterator, Attribute, HasState, Idtype> token_type;
  807. template <typename Out>
  808. static void print(Out& out, token_type const& val)
  809. {
  810. out << '[';
  811. spirit::traits::print_token(out, val.value());
  812. out << ']';
  813. }
  814. };
  815. }}}
  816. #endif