summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/core/parser.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3/core/parser.hpp')
-rw-r--r--boost/spirit/home/x3/core/parser.hpp239
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