annotate DEPENDENCIES/generic/include/boost/spirit/home/lex/lexer/lexertl/token.hpp @ 133:4acb5d8d80b6 tip

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