File indexing completed on 2025-01-31 10:02:35
0001
0002
0003
0004
0005
0006
0007
0008 #if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)
0009 #define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
0010
0011 #include <boost/mpl/bool.hpp>
0012 #include <boost/type_traits/is_base_of.hpp>
0013 #include <boost/type_traits/remove_cv.hpp>
0014 #include <boost/type_traits/remove_reference.hpp>
0015 #include <boost/utility/declval.hpp>
0016 #include <boost/utility/enable_if.hpp>
0017 #include <boost/spirit/home/x3/support/unused.hpp>
0018 #include <boost/spirit/home/x3/support/context.hpp>
0019 #include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
0020 #include <boost/core/ignore_unused.hpp>
0021 #include <boost/assert.hpp>
0022 #include <string>
0023
0024 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
0025 #include <typeinfo>
0026 #endif
0027
0028 namespace boost { namespace spirit { namespace x3
0029 {
0030 template <typename Subject, typename Action>
0031 struct action;
0032
0033 template <typename Subject, typename Handler>
0034 struct guard;
0035
0036 struct parser_base {};
0037 struct parser_id;
0038
0039 template <typename Derived>
0040 struct parser : parser_base
0041 {
0042 typedef Derived derived_type;
0043 static bool const handles_container = false;
0044 static bool const is_pass_through_unary = false;
0045 static bool const has_action = false;
0046
0047 constexpr Derived const& derived() const
0048 {
0049 return *static_cast<Derived const*>(this);
0050 }
0051
0052 template <typename Action>
0053 constexpr action<Derived, Action> operator[](Action f) const
0054 {
0055 return { this->derived(), f };
0056 }
0057
0058 template <typename Handler>
0059 constexpr guard<Derived, Handler> on_error(Handler f) const
0060 {
0061 return { this->derived(), f };
0062 }
0063 };
0064
0065 struct unary_category;
0066 struct binary_category;
0067
0068 template <typename Subject, typename Derived>
0069 struct unary_parser : parser<Derived>
0070 {
0071 typedef unary_category category;
0072 typedef Subject subject_type;
0073 static bool const has_action = Subject::has_action;
0074
0075 constexpr unary_parser(Subject const& subject)
0076 : subject(subject) {}
0077
0078 unary_parser const& get_unary() const { return *this; }
0079
0080 Subject subject;
0081 };
0082
0083 template <typename Left, typename Right, typename Derived>
0084 struct binary_parser : parser<Derived>
0085 {
0086 typedef binary_category category;
0087 typedef Left left_type;
0088 typedef Right right_type;
0089 static bool const has_action =
0090 left_type::has_action || right_type::has_action;
0091
0092 constexpr binary_parser(Left const& left, Right const& right)
0093 : left(left), right(right) {}
0094
0095 binary_parser const& get_binary() const { return *this; }
0096
0097 Left left;
0098 Right right;
0099 };
0100
0101
0102
0103
0104 namespace extension
0105 {
0106 namespace detail
0107 {
0108 namespace as_parser_guard
0109 {
0110 void as_spirit_parser(...);
0111
0112 template<typename T, typename R =
0113 decltype(as_spirit_parser(boost::declval<T const&>()))>
0114 struct deduce_as_parser
0115 {
0116 typedef R type;
0117 typedef typename
0118 boost::remove_cv<
0119 typename boost::remove_reference<R>::type
0120 >::type
0121 value_type;
0122
0123 static type call(T const& v)
0124 {
0125 return as_spirit_parser(v);
0126 }
0127 };
0128 template<typename T>
0129 struct deduce_as_parser<T, void>
0130 {};
0131 }
0132 using as_parser_guard::deduce_as_parser;
0133 }
0134
0135 template <typename T, typename Enable = void>
0136 struct as_parser : detail::deduce_as_parser<T> {};
0137
0138 template <>
0139 struct as_parser<unused_type>
0140 {
0141 typedef unused_type type;
0142 typedef unused_type value_type;
0143 static constexpr type call(unused_type)
0144 {
0145 return unused;
0146 }
0147 };
0148
0149 template <typename Derived>
0150 struct as_parser<Derived
0151 , typename enable_if<is_base_of<parser_base, Derived>>::type>
0152 {
0153 typedef Derived const& type;
0154 typedef Derived value_type;
0155 static constexpr type call(Derived const& p)
0156 {
0157 return p;
0158 }
0159 };
0160
0161 template <typename Derived>
0162 struct as_parser<parser<Derived>>
0163 {
0164 typedef Derived const& type;
0165 typedef Derived value_type;
0166 static constexpr type call(parser<Derived> const& p)
0167 {
0168 return p.derived();
0169 }
0170 };
0171 }
0172
0173 template <typename T>
0174 constexpr typename extension::as_parser<T>::type
0175 as_parser(T const& x)
0176 {
0177 return extension::as_parser<T>::call(x);
0178 }
0179
0180 template <typename Derived>
0181 constexpr Derived const&
0182 as_parser(parser<Derived> const& p)
0183 {
0184 return p.derived();
0185 }
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 template <typename Parser, typename Enable = void>
0198 struct get_info
0199 {
0200 typedef std::string result_type;
0201 std::string operator()(Parser const&) const
0202 {
0203 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
0204 return typeid(Parser).name();
0205 #else
0206 return "undefined";
0207 #endif
0208 }
0209 };
0210
0211 template <typename Parser>
0212 std::string what(Parser const& p)
0213 {
0214 return get_info<Parser>()(p);
0215 }
0216 }}}
0217
0218 namespace boost { namespace spirit { namespace x3 { namespace traits
0219 {
0220 template <typename Subject, typename Derived, typename Context>
0221 struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
0222 : has_attribute<Subject, Context> {};
0223
0224 template <typename Left, typename Right, typename Derived, typename Context>
0225 struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
0226 : mpl::bool_<has_attribute<Left, Context>::value ||
0227 has_attribute<Right, Context>::value> {};
0228 }}}}
0229
0230 #endif