File indexing completed on 2025-01-31 10:02:17
0001
0002
0003
0004
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
0036
0037
0038
0039 template <>
0040 struct use_terminal<qi::domain, tag::tokenid>
0041 : mpl::true_ {};
0042
0043
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
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
0059 template <>
0060 struct use_lazy_terminal<
0061 qi::domain, tag::tokenid, 1
0062 > : mpl::true_ {};
0063
0064
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
0080
0081
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& , Skipper const& skipper
0099 , Attribute& attr) const
0100 {
0101 qi::skip_over(first, last, skipper);
0102
0103 if (first != last) {
0104
0105
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& ) 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& , Skipper const& skipper
0151 , Attribute& attr) const
0152 {
0153 qi::skip_over(first, last, skipper);
0154
0155 if (first != last) {
0156
0157
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& ) 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
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