Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:16

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 // 
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying 
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_LEX_TOKEN_FEB_10_2008_0751PM)
0007 #define BOOST_SPIRIT_LEX_TOKEN_FEB_10_2008_0751PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/config.hpp>
0014 #include <boost/detail/workaround.hpp>
0015 #include <boost/spirit/home/qi/detail/assign_to.hpp>
0016 #include <boost/spirit/home/support/attributes.hpp>
0017 #include <boost/spirit/home/support/argument.hpp>
0018 #include <boost/spirit/home/support/detail/lexer/generator.hpp>
0019 #include <boost/spirit/home/support/detail/lexer/rules.hpp>
0020 #include <boost/spirit/home/support/detail/lexer/consts.hpp>
0021 #include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
0022 #include <boost/spirit/home/lex/lexer/terminals.hpp>
0023 #include <boost/fusion/include/vector.hpp>
0024 #include <boost/fusion/include/at.hpp>
0025 #include <boost/fusion/include/value_at.hpp>
0026 #include <boost/variant.hpp>
0027 #include <boost/mpl/bool.hpp>
0028 #include <boost/mpl/vector.hpp>
0029 #include <boost/mpl/is_sequence.hpp>
0030 #include <boost/mpl/begin.hpp>
0031 #include <boost/mpl/insert.hpp>
0032 #include <boost/mpl/vector.hpp>
0033 #include <boost/mpl/if.hpp>
0034 #include <boost/mpl/or.hpp>
0035 #include <boost/range/iterator_range_core.hpp>
0036 #include <boost/type_traits/is_same.hpp>
0037 #include <boost/type_traits/make_unsigned.hpp>
0038 #include <boost/static_assert.hpp>
0039 
0040 #if defined(BOOST_SPIRIT_DEBUG)
0041 #include <iosfwd>
0042 #endif
0043 
0044 namespace boost { namespace spirit { namespace lex { namespace lexertl
0045 { 
0046     ///////////////////////////////////////////////////////////////////////////
0047     //
0048     //  The token is the type of the objects returned by default by the 
0049     //  iterator.
0050     //
0051     //    template parameters:
0052     //        Iterator        The type of the iterator used to access the
0053     //                        underlying character stream.
0054     //        AttributeTypes  A mpl sequence containing the types of all 
0055     //                        required different token values to be supported 
0056     //                        by this token type.
0057     //        HasState        A mpl::bool_ indicating, whether this token type
0058     //                        should support lexer states.
0059     //        Idtype          The type to use for the token id (defaults to 
0060     //                        std::size_t).
0061     //
0062     //  It is possible to use other token types with the spirit::lex 
0063     //  framework as well. If you plan to use a different type as your token 
0064     //  type, you'll need to expose the following things from your token type 
0065     //  to make it compatible with spirit::lex:
0066     //
0067     //    typedefs
0068     //        iterator_type   The type of the iterator used to access the
0069     //                        underlying character stream.
0070     //
0071     //        id_type         The type of the token id used.
0072     //
0073     //    methods
0074     //        default constructor
0075     //                        This should initialize the token as an end of 
0076     //                        input token.
0077     //        constructors    The prototype of the other required 
0078     //                        constructors should be:
0079     //
0080     //              token(int)
0081     //                        This constructor should initialize the token as 
0082     //                        an invalid token (not carrying any specific 
0083     //                        values)
0084     //
0085     //              where:  the int is used as a tag only and its value is 
0086     //                      ignored
0087     //
0088     //                        and:
0089     //
0090     //              token(Idtype id, std::size_t state, 
0091     //                    iterator_type first, iterator_type last);
0092     //
0093     //              where:  id:           token id
0094     //                      state:        lexer state this token was matched in
0095     //                      first, last:  pair of iterators marking the matched 
0096     //                                    range in the underlying input stream 
0097     //
0098     //        accessors
0099     //              id()      return the token id of the matched input sequence
0100     //              id(newid) set the token id of the token instance
0101     //
0102     //              state()   return the lexer state this token was matched in
0103     //
0104     //              value()   return the token value
0105     //
0106     //  Additionally, you will have to implement a couple of helper functions
0107     //  in the same namespace as the token type: a comparison operator==() to 
0108     //  compare your token instances, a token_is_valid() function and different 
0109     //  specializations of the Spirit customization point 
0110     //  assign_to_attribute_from_value as shown below.
0111     //
0112     ///////////////////////////////////////////////////////////////////////////
0113     template <typename Iterator = char const*
0114       , typename AttributeTypes = mpl::vector0<>
0115       , typename HasState = mpl::true_
0116       , typename Idtype = std::size_t> 
0117     struct token;
0118 
0119     ///////////////////////////////////////////////////////////////////////////
0120     //  This specialization of the token type doesn't contain any item data and
0121     //  doesn't support working with lexer states.
0122     ///////////////////////////////////////////////////////////////////////////
0123     template <typename Iterator, typename Idtype>
0124     struct token<Iterator, lex::omit, mpl::false_, Idtype>
0125     {
0126         typedef Iterator iterator_type;
0127         typedef mpl::false_ has_state;
0128         typedef Idtype id_type;
0129         typedef unused_type token_value_type;
0130         typedef typename make_unsigned<id_type>::type uid_type;
0131 
0132         //  default constructed tokens correspond to EOI tokens
0133         token() : id_(boost::lexer::npos) {}
0134 
0135         //  construct an invalid token
0136         explicit token(int) : id_(0) {}
0137 
0138         token(id_type id, std::size_t) : id_(id) {}
0139 
0140         token(id_type id, std::size_t, token_value_type)
0141           : id_(id) {}
0142 
0143         token_value_type& value() { static token_value_type u; return u; }
0144         token_value_type const& value() const { return unused; }
0145 
0146 #if defined(BOOST_SPIRIT_DEBUG)
0147         token(id_type id, std::size_t, Iterator const& first
0148               , Iterator const& last)
0149           : matched_(first, last)
0150           , id_(id) {}
0151 #else
0152         token(id_type id, std::size_t, Iterator const&, Iterator const&)
0153           : id_(id) {}
0154 #endif
0155 
0156         //  this default conversion operator is needed to allow the direct 
0157         //  usage of tokens in conjunction with the primitive parsers defined 
0158         //  in Qi
0159         operator id_type() const { return id_type(uid_type(id_)); }
0160 
0161         //  Retrieve or set the token id of this token instance. 
0162         id_type id() const { return id_type(uid_type(id_)); }
0163         void id(id_type newid) { id_ = uid_type(newid); }
0164 
0165         std::size_t state() const { return 0; }   // always '0' (INITIAL state)
0166 
0167         bool is_valid() const 
0168         { 
0169             return 0 != id_ && boost::lexer::npos != id_; 
0170         }
0171 
0172 #if defined(BOOST_SPIRIT_DEBUG)
0173 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0174         // workaround for MSVC10 which has problems copying a default 
0175         // constructed iterator_range
0176         token& operator= (token const& rhs)
0177         {
0178             if (this != &rhs) 
0179             {
0180                 id_ = rhs.id_;
0181                 if (is_valid()) 
0182                     matched_ = rhs.matched_;
0183             }
0184             return *this;
0185         }
0186 #endif
0187         std::pair<Iterator, Iterator> matched_;
0188 #endif
0189 
0190     protected:
0191         std::size_t id_;            // token id, 0 if nothing has been matched
0192     };
0193 
0194 #if defined(BOOST_SPIRIT_DEBUG)
0195     template <typename Char, typename Traits, typename Iterator
0196       , typename AttributeTypes, typename HasState, typename Idtype> 
0197     inline std::basic_ostream<Char, Traits>& 
0198     operator<< (std::basic_ostream<Char, Traits>& os
0199       , token<Iterator, AttributeTypes, HasState, Idtype> const& t)
0200     {
0201         if (t.is_valid()) {
0202             Iterator end = t.matched_.second;
0203             for (Iterator it = t.matched_.first; it != end; ++it)
0204                 os << *it;
0205         }
0206         else {
0207             os << "<invalid token>";
0208         }
0209         return os;
0210     }
0211 #endif
0212 
0213     ///////////////////////////////////////////////////////////////////////////
0214     //  This specialization of the token type doesn't contain any item data but
0215     //  supports working with lexer states.
0216     ///////////////////////////////////////////////////////////////////////////
0217     template <typename Iterator, typename Idtype>
0218     struct token<Iterator, lex::omit, mpl::true_, Idtype>
0219       : token<Iterator, lex::omit, mpl::false_, Idtype>
0220     {
0221     private:
0222         typedef token<Iterator, lex::omit, mpl::false_, Idtype> base_type;
0223 
0224     public:
0225         typedef typename base_type::id_type id_type;
0226         typedef Iterator iterator_type;
0227         typedef mpl::true_ has_state;
0228         typedef unused_type token_value_type;
0229 
0230         //  default constructed tokens correspond to EOI tokens
0231         token() : state_(boost::lexer::npos) {}
0232 
0233         //  construct an invalid token
0234         explicit token(int) : base_type(0), state_(boost::lexer::npos) {}
0235 
0236         token(id_type id, std::size_t state)
0237           : base_type(id, boost::lexer::npos), state_(state) {}
0238 
0239         token(id_type id, std::size_t state, token_value_type)
0240           : base_type(id, boost::lexer::npos, unused)
0241           , state_(state) {}
0242 
0243         token(id_type id, std::size_t state
0244               , Iterator const& first, Iterator const& last)
0245           : base_type(id, boost::lexer::npos, first, last)
0246           , state_(state) {}
0247 
0248         std::size_t state() const { return state_; }
0249 
0250 #if defined(BOOST_SPIRIT_DEBUG) && BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0251         // workaround for MSVC10 which has problems copying a default 
0252         // constructed iterator_range
0253         token& operator= (token const& rhs)
0254         {
0255             if (this != &rhs) 
0256             {
0257                 this->base_type::operator=(static_cast<base_type const&>(rhs));
0258                 state_ = rhs.state_;
0259             }
0260             return *this;
0261         }
0262 #endif
0263 
0264     protected:
0265         std::size_t state_;      // lexer state this token was matched in
0266     };
0267 
0268     ///////////////////////////////////////////////////////////////////////////
0269     //  The generic version of the token type derives from the 
0270     //  specialization above and adds a single data member holding the item 
0271     //  data carried by the token instance.
0272     ///////////////////////////////////////////////////////////////////////////
0273     namespace detail
0274     {
0275         ///////////////////////////////////////////////////////////////////////
0276         //  Meta-function to calculate the type of the variant data item to be 
0277         //  stored with each token instance.
0278         //
0279         //  Note: The iterator pair needs to be the first type in the list of 
0280         //        types supported by the generated variant type (this is being 
0281         //        used to identify whether the stored data item in a particular 
0282         //        token instance needs to be converted from the pair of 
0283         //        iterators (see the first of the assign_to_attribute_from_value 
0284         //        specializations below).
0285         ///////////////////////////////////////////////////////////////////////
0286         template <typename IteratorPair, typename AttributeTypes>
0287         struct token_value_typesequence
0288         {
0289             typedef typename mpl::insert<
0290                 AttributeTypes
0291               , typename mpl::begin<AttributeTypes>::type
0292               , IteratorPair
0293             >::type sequence_type;
0294             typedef typename make_variant_over<sequence_type>::type type;
0295         };
0296 
0297         ///////////////////////////////////////////////////////////////////////
0298         //  The type of the data item stored with a token instance is defined 
0299         //  by the template parameter 'AttributeTypes' and may be:
0300         //  
0301         //     lex::omit:         no data item is stored with the token 
0302         //                        instance (this is handled by the 
0303         //                        specializations of the token class
0304         //                        below)
0305         //     mpl::vector0<>:    each token instance stores a pair of 
0306         //                        iterators pointing to the matched input 
0307         //                        sequence
0308         //     mpl::vector<...>:  each token instance stores a variant being 
0309         //                        able to store the pair of iterators pointing 
0310         //                        to the matched input sequence, or any of the 
0311         //                        types a specified in the mpl::vector<>
0312         //
0313         //  All this is done to ensure the token type is as small (in terms 
0314         //  of its byte-size) as possible.
0315         ///////////////////////////////////////////////////////////////////////
0316         template <typename IteratorPair, typename AttributeTypes>
0317         struct token_value_type
0318           : mpl::eval_if<
0319                 mpl::or_<
0320                     is_same<AttributeTypes, mpl::vector0<> >
0321                   , is_same<AttributeTypes, mpl::vector<> > >
0322               , mpl::identity<IteratorPair>
0323               , token_value_typesequence<IteratorPair, AttributeTypes> >
0324         {};
0325     }
0326 
0327     template <typename Iterator, typename AttributeTypes, typename HasState
0328       , typename Idtype>
0329     struct token : token<Iterator, lex::omit, HasState, Idtype>
0330     {
0331     private: // precondition assertions
0332         BOOST_STATIC_ASSERT((mpl::is_sequence<AttributeTypes>::value || 
0333                             is_same<AttributeTypes, lex::omit>::value));
0334         typedef token<Iterator, lex::omit, HasState, Idtype> base_type;
0335 
0336     protected: 
0337         //  If no additional token value types are given, the token will 
0338         //  hold the plain pair of iterators pointing to the matched range
0339         //  in the underlying input sequence. Otherwise the token value is 
0340         //  stored as a variant and will again hold the pair of iterators but
0341         //  is able to hold any of the given data types as well. The conversion 
0342         //  from the iterator pair to the required data type is done when it is
0343         //  accessed for the first time.
0344         typedef iterator_range<Iterator> iterpair_type;
0345 
0346     public:
0347         typedef typename base_type::id_type id_type;
0348         typedef typename detail::token_value_type<
0349             iterpair_type, AttributeTypes
0350         >::type token_value_type;
0351 
0352         typedef Iterator iterator_type;
0353 
0354         //  default constructed tokens correspond to EOI tokens
0355         token() : value_(iterpair_type(iterator_type(), iterator_type())) {}
0356 
0357         //  construct an invalid token
0358         explicit token(int)
0359           : base_type(0)
0360           , value_(iterpair_type(iterator_type(), iterator_type())) {}
0361 
0362         token(id_type id, std::size_t state, token_value_type const& value)
0363           : base_type(id, state, value)
0364           , value_(value) {}
0365 
0366         token(id_type id, std::size_t state, Iterator const& first
0367               , Iterator const& last)
0368           : base_type(id, state, first, last)
0369           , value_(iterpair_type(first, last)) {}
0370 
0371         token_value_type& value() { return value_; }
0372         token_value_type const& value() const { return value_; }
0373 
0374 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0375         // workaround for MSVC10 which has problems copying a default 
0376         // constructed iterator_range
0377         token& operator= (token const& rhs)
0378         {
0379             if (this != &rhs) 
0380             {
0381                 this->base_type::operator=(static_cast<base_type const&>(rhs));
0382                 if (this->is_valid()) 
0383                     value_ = rhs.value_;
0384             }
0385             return *this;
0386         }
0387 #endif
0388 
0389     protected:
0390         token_value_type value_; // token value, by default a pair of iterators
0391     };
0392 
0393     ///////////////////////////////////////////////////////////////////////////
0394     //  tokens are considered equal, if their id's match (these are unique)
0395     template <typename Iterator, typename AttributeTypes, typename HasState
0396       , typename Idtype>
0397     inline bool 
0398     operator== (token<Iterator, AttributeTypes, HasState, Idtype> const& lhs, 
0399                 token<Iterator, AttributeTypes, HasState, Idtype> const& rhs)
0400     {
0401         return lhs.id() == rhs.id();
0402     }
0403 
0404     ///////////////////////////////////////////////////////////////////////////
0405     //  This overload is needed by the multi_pass/functor_input_policy to 
0406     //  validate a token instance. It has to be defined in the same namespace 
0407     //  as the token class itself to allow ADL to find it.
0408     ///////////////////////////////////////////////////////////////////////////
0409     template <typename Iterator, typename AttributeTypes, typename HasState
0410       , typename Idtype>
0411     inline bool 
0412     token_is_valid(token<Iterator, AttributeTypes, HasState, Idtype> const& t)
0413     {
0414         return t.is_valid();
0415     }
0416 }}}}
0417 
0418 namespace boost { namespace spirit { namespace traits
0419 {
0420     ///////////////////////////////////////////////////////////////////////////
0421     //  We have to provide specializations for the customization point
0422     //  assign_to_attribute_from_value allowing to extract the needed value 
0423     //  from the token. 
0424     ///////////////////////////////////////////////////////////////////////////
0425 
0426     //  This is called from the parse function of token_def if the token_def
0427     //  has been defined to carry a special attribute type
0428     template <typename Attribute, typename Iterator, typename AttributeTypes
0429       , typename HasState, typename Idtype>
0430     struct assign_to_attribute_from_value<Attribute
0431       , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0432     {
0433         static void 
0434         call(lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> const& t
0435           , Attribute& attr)
0436         {
0437         //  The goal of this function is to avoid the conversion of the pair of
0438         //  iterators (to the matched character sequence) into the token value 
0439         //  of the required type being done more than once. For this purpose it 
0440         //  checks whether the stored value type is still the default one (pair 
0441         //  of iterators) and if yes, replaces the pair of iterators with the 
0442         //  converted value to be returned from subsequent calls.
0443 
0444             if (0 == t.value().which()) {
0445             //  first access to the token value
0446                 typedef iterator_range<Iterator> iterpair_type;
0447                 iterpair_type const& ip = boost::get<iterpair_type>(t.value());
0448 
0449             // Interestingly enough we use the assign_to() framework defined in 
0450             // Spirit.Qi allowing to convert the pair of iterators to almost any 
0451             // required type (assign_to(), if available, uses the standard Spirit 
0452             // parsers to do the conversion).
0453                 spirit::traits::assign_to(ip.begin(), ip.end(), attr);
0454 
0455             //  If you get an error during the compilation of the following 
0456             //  assignment expression, you probably forgot to list one or more 
0457             //  types used as token value types (in your token_def<...> 
0458             //  definitions) in your definition of the token class. I.e. any token 
0459             //  value type used for a token_def<...> definition has to be listed 
0460             //  during the declaration of the token type to use. For instance let's 
0461             //  assume we have two token_def's:
0462             //
0463             //      token_def<int> number; number = "...";
0464             //      token_def<std::string> identifier; identifier = "...";
0465             //
0466             //  Then you'll have to use the following token type definition 
0467             //  (assuming you are using the token class):
0468             //
0469             //      typedef mpl::vector<int, std::string> token_values;
0470             //      typedef token<base_iter_type, token_values> token_type;
0471             //
0472             //  where: base_iter_type is the iterator type used to expose the 
0473             //         underlying input stream.
0474             //
0475             //  This token_type has to be used as the second template parameter 
0476             //  to the lexer class:
0477             //
0478             //      typedef lexer<base_iter_type, token_type> lexer_type;
0479             //
0480             //  again, assuming you're using the lexer<> template for your 
0481             //  tokenization.
0482 
0483                 typedef lex::lexertl::token<
0484                     Iterator, AttributeTypes, HasState, Idtype> token_type;
0485                 spirit::traits::assign_to(
0486                     attr, const_cast<token_type&>(t).value());   // re-assign value
0487             }
0488             else {
0489             // reuse the already assigned value
0490                 spirit::traits::assign_to(boost::get<Attribute>(t.value()), attr);
0491             }
0492         }
0493     };
0494 
0495     template <typename Attribute, typename Iterator, typename AttributeTypes
0496       , typename HasState, typename Idtype>
0497     struct assign_to_container_from_value<Attribute
0498           , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0499       : assign_to_attribute_from_value<Attribute
0500           , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0501     {};
0502 
0503     template <typename Iterator, typename AttributeTypes
0504       , typename HasState, typename Idtype>
0505     struct assign_to_container_from_value<utree
0506           , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0507       : assign_to_attribute_from_value<utree
0508           , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0509     {};
0510 
0511     template <typename Iterator>
0512     struct assign_to_container_from_value<
0513         iterator_range<Iterator>, iterator_range<Iterator> >
0514     {
0515         static void 
0516         call(iterator_range<Iterator> const& val, iterator_range<Iterator>& attr)
0517         {
0518             attr = val;
0519         }
0520     };
0521 
0522     //  These are called from the parse function of token_def if the token type
0523     //  has no special attribute type assigned 
0524     template <typename Attribute, typename Iterator, typename HasState
0525       , typename Idtype>
0526     struct assign_to_attribute_from_value<Attribute
0527       , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> >
0528     {
0529         static void 
0530         call(lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> const& t
0531           , Attribute& attr)
0532         {
0533             //  The default type returned by the token_def parser component (if 
0534             //  it has no token value type assigned) is the pair of iterators 
0535             //  to the matched character sequence.
0536             spirit::traits::assign_to(t.value().begin(), t.value().end(), attr);
0537         }
0538     };
0539 
0540 //     template <typename Attribute, typename Iterator, typename HasState
0541 //       , typename Idtype>
0542 //     struct assign_to_container_from_value<Attribute
0543 //           , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> >
0544 //       : assign_to_attribute_from_value<Attribute
0545 //           , lex::lexertl::token<Iterator, mpl::vector0<>, HasState, Idtype> >
0546 //     {};
0547 
0548     // same as above but using mpl::vector<> instead of mpl::vector0<>
0549     template <typename Attribute, typename Iterator, typename HasState
0550       , typename Idtype>
0551     struct assign_to_attribute_from_value<Attribute
0552       , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> >
0553     {
0554         static void 
0555         call(lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> const& t
0556           , Attribute& attr)
0557         {
0558             //  The default type returned by the token_def parser component (if 
0559             //  it has no token value type assigned) is the pair of iterators 
0560             //  to the matched character sequence.
0561             spirit::traits::assign_to(t.value().begin(), t.value().end(), attr);
0562         }
0563     };
0564 
0565 //     template <typename Attribute, typename Iterator, typename HasState
0566 //       , typename Idtype>
0567 //     struct assign_to_container_from_value<Attribute
0568 //           , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> >
0569 //       : assign_to_attribute_from_value<Attribute
0570 //           , lex::lexertl::token<Iterator, mpl::vector<>, HasState, Idtype> >
0571 //     {};
0572 
0573     //  This is called from the parse function of token_def if the token type
0574     //  has been explicitly omitted (i.e. no attribute value is used), which
0575     //  essentially means that every attribute gets initialized using default 
0576     //  constructed values.
0577     template <typename Attribute, typename Iterator, typename HasState
0578       , typename Idtype>
0579     struct assign_to_attribute_from_value<Attribute
0580       , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> >
0581     {
0582         static void 
0583         call(lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> const&
0584           , Attribute&)
0585         {
0586             // do nothing
0587         }
0588     };
0589 
0590     template <typename Attribute, typename Iterator, typename HasState
0591       , typename Idtype>
0592     struct assign_to_container_from_value<Attribute
0593           , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> >
0594       : assign_to_attribute_from_value<Attribute
0595           , lex::lexertl::token<Iterator, lex::omit, HasState, Idtype> >
0596     {};
0597 
0598     //  This is called from the parse function of lexer_def_
0599     template <typename Iterator, typename AttributeTypes, typename HasState
0600       , typename Idtype_, typename Idtype>
0601     struct assign_to_attribute_from_value<
0602         fusion::vector2<Idtype_, iterator_range<Iterator> >
0603       , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0604     {
0605         static void 
0606         call(lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> const& t
0607           , fusion::vector2<Idtype_, iterator_range<Iterator> >& attr)
0608         {
0609             //  The type returned by the lexer_def_ parser components is a 
0610             //  fusion::vector containing the token id of the matched token 
0611             //  and the pair of iterators to the matched character sequence.
0612             typedef iterator_range<Iterator> iterpair_type;
0613             typedef fusion::vector2<Idtype_, iterator_range<Iterator> > 
0614                 attribute_type;
0615 
0616             iterpair_type const& ip = boost::get<iterpair_type>(t.value());
0617             attr = attribute_type(t.id(), ip);
0618         }
0619     };
0620 
0621     template <typename Iterator, typename AttributeTypes, typename HasState
0622       , typename Idtype_, typename Idtype>
0623     struct assign_to_container_from_value<
0624             fusion::vector2<Idtype_, iterator_range<Iterator> >
0625           , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0626       : assign_to_attribute_from_value<
0627             fusion::vector2<Idtype_, iterator_range<Iterator> >
0628           , lex::lexertl::token<Iterator, AttributeTypes, HasState, Idtype> >
0629     {};
0630 
0631     ///////////////////////////////////////////////////////////////////////////
0632     // Overload debug output for a single token, this integrates lexer tokens 
0633     // with Qi's simple_trace debug facilities
0634     template <typename Iterator, typename Attribute, typename HasState
0635       , typename Idtype>
0636     struct token_printer_debug<
0637         lex::lexertl::token<Iterator, Attribute, HasState, Idtype> >
0638     {
0639         typedef lex::lexertl::token<Iterator, Attribute, HasState, Idtype> token_type;
0640 
0641         template <typename Out>
0642         static void print(Out& out, token_type const& val) 
0643         {
0644             out << '[';
0645             spirit::traits::print_token(out, val.value());
0646             out << ']';
0647         }
0648     };
0649 }}}
0650 
0651 #endif