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_TOKEN_NOV_11_2007_0451PM)
0007 #define BOOST_SPIRIT_LEX_PLAIN_TOKEN_NOV_11_2007_0451PM
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/range/iterator_range_core.hpp>
0028 #include <boost/type_traits/is_integral.hpp>
0029 #include <boost/type_traits/is_enum.hpp>
0030 #include <iterator> // for std::iterator_traits
0031 #include <sstream>
0032 
0033 namespace boost { namespace spirit
0034 {
0035     ///////////////////////////////////////////////////////////////////////////
0036     // Enablers
0037     ///////////////////////////////////////////////////////////////////////////
0038 
0039     // enables token
0040     template <>
0041     struct use_terminal<qi::domain, tag::token>
0042       : mpl::true_ {};
0043 
0044     // enables token(id)
0045     template <typename A0>
0046     struct use_terminal<qi::domain
0047       , terminal_ex<tag::token, fusion::vector1<A0> >
0048     > : mpl::or_<is_integral<A0>, is_enum<A0> > {};
0049 
0050     // enables token(idmin, idmax)
0051     template <typename A0, typename A1>
0052     struct use_terminal<qi::domain
0053       , terminal_ex<tag::token, fusion::vector2<A0, A1> >
0054     > : mpl::and_<
0055             mpl::or_<is_integral<A0>, is_enum<A0> >
0056           , mpl::or_<is_integral<A1>, is_enum<A1> >
0057         > {};
0058 
0059     // enables *lazy* token(id)
0060     template <>
0061     struct use_lazy_terminal<
0062         qi::domain, tag::token, 1
0063     > : mpl::true_ {};
0064 
0065     // enables *lazy* token(idmin, idmax)
0066     template <>
0067     struct use_lazy_terminal<
0068         qi::domain, tag::token, 2
0069     > : mpl::true_ {};
0070 }}
0071 
0072 namespace boost { namespace spirit { namespace qi
0073 {
0074 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0075     using spirit::token;
0076 #endif
0077     using spirit::token_type;
0078 
0079     ///////////////////////////////////////////////////////////////////////////
0080     template <typename TokenId>
0081     struct plain_token
0082       : primitive_parser<plain_token<TokenId> >
0083     {
0084         template <typename Context, typename Iterator>
0085         struct attribute
0086         {
0087             typedef typename Iterator::base_iterator_type iterator_type;
0088             typedef iterator_range<iterator_type> type;
0089         };
0090 
0091         plain_token(TokenId const& id)
0092           : id(id) {}
0093 
0094         template <typename Iterator, typename Context
0095           , typename Skipper, typename Attribute>
0096         bool parse(Iterator& first, Iterator const& last
0097           , Context& /*context*/, Skipper const& skipper
0098           , Attribute& attr) const
0099         {
0100             qi::skip_over(first, last, skipper);   // always do a pre-skip
0101 
0102             if (first != last) {
0103                 // simply match the token id with the id this component has
0104                 // been initialized with
0105 
0106                 typedef typename
0107                     std::iterator_traits<Iterator>::value_type
0108                 token_type;
0109                 typedef typename token_type::id_type id_type;
0110 
0111                 token_type const& t = *first;
0112                 if (id_type(~0) == id_type(id) || id_type(id) == t.id()) {
0113                     spirit::traits::assign_to(t, attr);
0114                     ++first;
0115                     return true;
0116                 }
0117             }
0118             return false;
0119         }
0120 
0121         template <typename Context>
0122         info what(Context& /*context*/) const
0123         {
0124             std::stringstream ss;
0125             ss << "token(" << id << ")";
0126             return info("token", ss.str());
0127         }
0128 
0129         TokenId id;
0130     };
0131 
0132     ///////////////////////////////////////////////////////////////////////////
0133     template <typename TokenId>
0134     struct plain_token_range
0135       : primitive_parser<plain_token_range<TokenId> >
0136     {
0137         template <typename Context, typename Iterator>
0138         struct attribute
0139         {
0140             typedef typename Iterator::base_iterator_type iterator_type;
0141             typedef iterator_range<iterator_type> type;
0142         };
0143 
0144         plain_token_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(idmax) >= t.id() && id_type(idmin) <= t.id())
0166                 {
0167                     spirit::traits::assign_to(t, 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("token_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::token, Modifiers>
0191     {
0192         typedef plain_token<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::token, fusion::vector1<TokenId> >
0202       , Modifiers>
0203     {
0204         typedef plain_token<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::token, fusion::vector2<TokenId, TokenId> >
0215       , Modifiers>
0216     {
0217         typedef plain_token_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_token<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_token_range<Idtype>, Attr, Context, Iterator>
0238       : mpl::true_
0239     {};
0240 }}}
0241 
0242 #endif