Back to home page

EIC code displayed by LXR

 
 

    


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

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_PLAIN_TOKENID_NOV_26_2010_0944AM)
0007 #define BOOST_SPIRIT_LEX_PLAIN_TOKENID_NOV_26_2010_0944AM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/support/info.hpp>
0014 #include <boost/spirit/home/qi/detail/attributes.hpp>
0015 #include <boost/spirit/home/support/common_terminals.hpp>
0016 #include <boost/spirit/home/support/handles_container.hpp>
0017 #include <boost/spirit/home/qi/skip_over.hpp>
0018 #include <boost/spirit/home/qi/domain.hpp>
0019 #include <boost/spirit/home/qi/parser.hpp>
0020 #include <boost/spirit/home/qi/meta_compiler.hpp>
0021 #include <boost/spirit/home/qi/detail/assign_to.hpp>
0022 
0023 #include <boost/fusion/include/vector.hpp>
0024 #include <boost/fusion/include/at.hpp>
0025 #include <boost/mpl/or.hpp>
0026 #include <boost/mpl/and.hpp>
0027 #include <boost/type_traits/is_integral.hpp>
0028 #include <boost/type_traits/is_enum.hpp>
0029 #include <iterator> // for std::iterator_traits
0030 #include <sstream>
0031 
0032 namespace boost { namespace spirit
0033 {
0034     ///////////////////////////////////////////////////////////////////////////
0035     // Enablers
0036     ///////////////////////////////////////////////////////////////////////////
0037 
0038     // enables tokenid
0039     template <>
0040     struct use_terminal<qi::domain, tag::tokenid>
0041       : mpl::true_ {};
0042 
0043     // enables tokenid(id)
0044     template <typename A0>
0045     struct use_terminal<qi::domain
0046       , terminal_ex<tag::tokenid, fusion::vector1<A0> >
0047     > : mpl::or_<is_integral<A0>, is_enum<A0> > {};
0048 
0049     // enables tokenid(idmin, idmax)
0050     template <typename A0, typename A1>
0051     struct use_terminal<qi::domain
0052       , terminal_ex<tag::tokenid, fusion::vector2<A0, A1> >
0053     > : mpl::and_<
0054             mpl::or_<is_integral<A0>, is_enum<A0> >
0055           , mpl::or_<is_integral<A1>, is_enum<A1> >
0056         > {};
0057 
0058     // enables *lazy* tokenid(id)
0059     template <>
0060     struct use_lazy_terminal<
0061         qi::domain, tag::tokenid, 1
0062     > : mpl::true_ {};
0063 
0064     // enables *lazy* tokenid(idmin, idmax)
0065     template <>
0066     struct use_lazy_terminal<
0067         qi::domain, tag::tokenid, 2
0068     > : mpl::true_ {};
0069 }}
0070 
0071 namespace boost { namespace spirit { namespace qi
0072 {
0073 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0074     using spirit::tokenid;
0075 #endif
0076     using spirit::tokenid_type;
0077 
0078     ///////////////////////////////////////////////////////////////////////////
0079     // The plain_tokenid represents a simple token defined by the lexer inside
0080     // a Qi grammar. The difference to plain_token is that it exposes the
0081     // matched token id instead of the iterator_range of the matched input.
0082     template <typename TokenId>
0083     struct plain_tokenid
0084       : primitive_parser<plain_tokenid<TokenId> >
0085     {
0086         template <typename Context, typename Iterator>
0087         struct attribute
0088         {
0089             typedef TokenId type;
0090         };
0091 
0092         plain_tokenid(TokenId const& id)
0093           : id(id) {}
0094 
0095         template <typename Iterator, typename Context
0096           , typename Skipper, typename Attribute>
0097         bool parse(Iterator& first, Iterator const& last
0098           , Context& /*context*/, Skipper const& skipper
0099           , Attribute& attr) const
0100         {
0101             qi::skip_over(first, last, skipper);   // always do a pre-skip
0102 
0103             if (first != last) {
0104                 // simply match the token id with the id this component has
0105                 // been initialized with
0106 
0107                 typedef typename
0108                     std::iterator_traits<Iterator>::value_type
0109                 token_type;
0110                 typedef typename token_type::id_type id_type;
0111 
0112                 token_type const& t = *first;
0113                 if (id_type(~0) == id_type(id) || id_type(id) == t.id()) {
0114                     spirit::traits::assign_to(id, attr);
0115                     ++first;
0116                     return true;
0117                 }
0118             }
0119             return false;
0120         }
0121 
0122         template <typename Context>
0123         info what(Context& /*context*/) const
0124         {
0125             std::stringstream ss;
0126             ss << "tokenid(" << id << ")";
0127             return info("tokenid", ss.str());
0128         }
0129 
0130         TokenId id;
0131     };
0132 
0133     ///////////////////////////////////////////////////////////////////////////
0134     template <typename TokenId>
0135     struct plain_tokenid_range
0136       : primitive_parser<plain_tokenid_range<TokenId> >
0137     {
0138         template <typename Context, typename Iterator>
0139         struct attribute
0140         {
0141             typedef TokenId type;
0142         };
0143 
0144         plain_tokenid_range(TokenId const& idmin, TokenId const& idmax)
0145           : idmin(idmin), idmax(idmax) {}
0146 
0147         template <typename Iterator, typename Context
0148           , typename Skipper, typename Attribute>
0149         bool parse(Iterator& first, Iterator const& last
0150           , Context& /*context*/, Skipper const& skipper
0151           , Attribute& attr) const
0152         {
0153             qi::skip_over(first, last, skipper);   // always do a pre-skip
0154 
0155             if (first != last) {
0156                 // simply match the token id with the id this component has
0157                 // been initialized with
0158 
0159                 typedef typename
0160                     std::iterator_traits<Iterator>::value_type
0161                 token_type;
0162                 typedef typename token_type::id_type id_type;
0163 
0164                 token_type const& t = *first;
0165                 if (id_type(idmin) >= t.id() && id_type(idmin) <= t.id())
0166                 {
0167                     spirit::traits::assign_to(t.id(), attr);
0168                     ++first;
0169                     return true;
0170                 }
0171             }
0172             return false;
0173         }
0174 
0175         template <typename Context>
0176         info what(Context& /*context*/) const
0177         {
0178             std::stringstream ss;
0179             ss << "token(" << idmin << ", " << idmax << ")";
0180             return info("tokenid_range", ss.str());
0181         }
0182 
0183         TokenId idmin, idmax;
0184     };
0185 
0186     ///////////////////////////////////////////////////////////////////////////
0187     // Parser generators: make_xxx function (objects)
0188     ///////////////////////////////////////////////////////////////////////////
0189     template <typename Modifiers>
0190     struct make_primitive<tag::tokenid, Modifiers>
0191     {
0192         typedef plain_tokenid<std::size_t> result_type;
0193 
0194         result_type operator()(unused_type, unused_type) const
0195         {
0196             return result_type(std::size_t(~0));
0197         }
0198     };
0199 
0200     template <typename Modifiers, typename TokenId>
0201     struct make_primitive<terminal_ex<tag::tokenid, fusion::vector1<TokenId> >
0202       , Modifiers>
0203     {
0204         typedef plain_tokenid<TokenId> result_type;
0205 
0206         template <typename Terminal>
0207         result_type operator()(Terminal const& term, unused_type) const
0208         {
0209             return result_type(fusion::at_c<0>(term.args));
0210         }
0211     };
0212 
0213     template <typename Modifiers, typename TokenId>
0214     struct make_primitive<terminal_ex<tag::tokenid, fusion::vector2<TokenId, TokenId> >
0215       , Modifiers>
0216     {
0217         typedef plain_tokenid_range<TokenId> result_type;
0218 
0219         template <typename Terminal>
0220         result_type operator()(Terminal const& term, unused_type) const
0221         {
0222             return result_type(fusion::at_c<0>(term.args)
0223               , fusion::at_c<1>(term.args));
0224         }
0225     };
0226 }}}
0227 
0228 namespace boost { namespace spirit { namespace traits
0229 {
0230     ///////////////////////////////////////////////////////////////////////////
0231     template<typename Idtype, typename Attr, typename Context, typename Iterator>
0232     struct handles_container<qi::plain_tokenid<Idtype>, Attr, Context, Iterator>
0233       : mpl::true_
0234     {};
0235 
0236     template<typename Idtype, typename Attr, typename Context, typename Iterator>
0237     struct handles_container<qi::plain_tokenid_range<Idtype>, Attr, Context, Iterator>
0238       : mpl::true_
0239     {};
0240 }}}
0241 
0242 #endif