diff options
Diffstat (limited to 'boost/spirit/home/x3/core/parser.hpp')
-rw-r--r-- | boost/spirit/home/x3/core/parser.hpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/core/parser.hpp b/boost/spirit/home/x3/core/parser.hpp new file mode 100644 index 0000000000..bc63a7438b --- /dev/null +++ b/boost/spirit/home/x3/core/parser.hpp @@ -0,0 +1,239 @@ +/*============================================================================= + Copyright (c) 2001-2014 Joel de Guzman + Copyright (c) 2013 Agustin Berge + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ +#if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM) +#define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/mpl/bool.hpp> +#include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/utility/declval.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/spirit/home/x3/support/unused.hpp> +#include <boost/spirit/home/x3/support/context.hpp> +#include <boost/spirit/home/x3/support/traits/has_attribute.hpp> +#include <boost/spirit/home/x3/support/utility/sfinae.hpp> +#include <string> + +#if !defined(BOOST_SPIRIT_X3_NO_RTTI) +#include <typeinfo> +#endif + +namespace boost { namespace spirit { namespace x3 +{ + using x3::unused_type; + using x3::unused; + using x3::get; + + template <typename Subject, typename Action> + struct action; + + template <typename Subject, typename Handler> + struct guard; + + struct parser_base {}; + struct parser_id; + + template <typename Derived> + struct parser : parser_base + { + typedef Derived derived_type; + static bool const handles_container = false; + static bool const is_pass_through_unary = false; + static bool const has_action = false; + + Derived const& derived() const + { + return *static_cast<Derived const*>(this); + } + + template <typename Action> + action<Derived, Action> + operator[](Action f) const + { + return action<Derived, Action>(this->derived(), f); + } + + template <typename Handler> + guard<Derived, Handler> + on_error(Handler f) const + { + return guard<Derived, Handler>(this->derived(), f); + } + }; + + struct unary_category; + struct binary_category; + + template <typename Subject, typename Derived> + struct unary_parser : parser<Derived> + { + typedef unary_category category; + typedef Subject subject_type; + static bool const has_action = Subject::has_action; + + unary_parser(Subject subject) + : subject(subject) {} + + unary_parser const& get_unary() const { return *this; } + + Subject subject; + }; + + template <typename Left, typename Right, typename Derived> + struct binary_parser : parser<Derived> + { + typedef binary_category category; + typedef Left left_type; + typedef Right right_type; + static bool const has_action = + left_type::has_action || right_type::has_action; + + binary_parser(Left left, Right right) + : left(left), right(right) {} + + binary_parser const& get_binary() const { return *this; } + + Left left; + Right right; + }; + + /////////////////////////////////////////////////////////////////////////// + // as_parser: convert a type, T, into a parser. + /////////////////////////////////////////////////////////////////////////// + namespace extension + { + namespace detail + { + namespace as_parser_guard + { + void as_spirit_parser(...); + + template<typename T, typename R = + decltype(as_spirit_parser(boost::declval<T const&>()))> + struct deduce_as_parser + { + typedef R type; + typedef typename + boost::remove_cv< + typename boost::remove_reference<R>::type + >::type + value_type; + + static type call(T const& v) + { + return as_spirit_parser(v); + } + }; + template<typename T> + struct deduce_as_parser<T, void> + {}; + } + using as_parser_guard::deduce_as_parser; + } + + template <typename T, typename Enable = void> + struct as_parser : detail::deduce_as_parser<T> {}; + + template <> + struct as_parser<unused_type> + { + typedef unused_type type; + typedef unused_type value_type; + static type call(unused_type) + { + return unused; + } + }; + + template <typename Derived> + struct as_parser<Derived + , typename enable_if<is_base_of<parser_base, Derived>>::type> + { + typedef Derived const& type; + typedef Derived value_type; + static type call(Derived const& p) + { + return p; + } + }; + + template <typename Derived> + struct as_parser<parser<Derived>> + { + typedef Derived const& type; + typedef Derived value_type; + static type call(parser<Derived> const& p) + { + return p.derived(); + } + }; + } + + template <typename T> + inline typename extension::as_parser<T>::type + as_parser(T const& x) + { + return extension::as_parser<T>::call(x); + } + + template <typename Derived> + inline Derived const& + as_parser(parser<Derived> const& p) + { + return p.derived(); + } + + /////////////////////////////////////////////////////////////////////////// + // The main what function + // + // Note: unlike Spirit2, spirit parsers are no longer required to have a + // "what" member function. In X3, we specialize the get_info struct + // below where needed. If a specialization is not provided, the default + // below will be used. The default "what" result will be the typeid + // name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise + // "undefined" + /////////////////////////////////////////////////////////////////////////// + template <typename Parser, typename Enable = void> + struct get_info + { + typedef std::string result_type; + std::string operator()(Parser const&) const + { +#if !defined(BOOST_SPIRIT_X3_NO_RTTI) + return typeid(Parser).name(); +#else + return "undefined"; +#endif + } + }; + + template <typename Parser> + std::string what(Parser const& p) + { + return get_info<Parser>()(p); + } +}}} + +namespace boost { namespace spirit { namespace x3 { namespace traits +{ + template <typename Subject, typename Derived, typename Context> + struct has_attribute<x3::unary_parser<Subject, Derived>, Context> + : has_attribute<Subject, Context> {}; + + template <typename Left, typename Right, typename Derived, typename Context> + struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context> + : mpl::bool_<has_attribute<Left, Context>::value || + has_attribute<Right, Context>::value> {}; +}}}} + +#endif |