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