diff options
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp new file mode 100644 index 0000000..9f10306 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/impl/rule.ipp @@ -0,0 +1,420 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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_RULE_IPP) +#define BOOST_SPIRIT_RULE_IPP + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/repeat_from_to.hpp> +#include <boost/preprocessor/enum_params.hpp> +#include <boost/preprocessor/enum_params_with_defaults.hpp> +#include <boost/preprocessor/facilities/intercept.hpp> +#include <boost/preprocessor/inc.hpp> +#include <boost/preprocessor/cat.hpp> +#endif + +#include <boost/spirit/home/classic/core/parser.hpp> +#include <boost/spirit/home/classic/core/scanner/scanner.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> +#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp> +#include <boost/type_traits/is_base_and_derived.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + template < + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT + ) + > + struct scanner_list; + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////////// + namespace impl + { + template <typename BaseT, typename DefaultT + , typename T0, typename T1, typename T2> + struct get_param + { + typedef typename mpl::if_< + is_base_and_derived<BaseT, T0> + , T0 + , typename mpl::if_< + is_base_and_derived<BaseT, T1> + , T1 + , typename mpl::if_< + is_base_and_derived<BaseT, T2> + , T2 + , DefaultT + >::type + >::type + >::type type; + }; + + template <typename T0, typename T1, typename T2> + struct get_context + { + typedef typename get_param< + parser_context_base, parser_context<>, T0, T1, T2>::type + type; + }; + + template <typename T0, typename T1, typename T2> + struct get_tag + { + typedef typename get_param< + parser_tag_base, parser_address_tag, T0, T1, T2>::type + type; + }; + + template <typename T0, typename T1, typename T2> + struct get_scanner + { + typedef typename get_param< + scanner_base, scanner<>, T0, T1, T2>::type + type; + }; + + /////////////////////////////////////////////////////////////////////// + // + // rule_base class + // + // The rule_base class implements the basic plumbing for rules + // minus the storage mechanism. It is up to the derived class + // to actually store the definition somewhere. The rule_base + // class assumes that the derived class provides a get() function + // that will return a pointer to a parser. The get() function + // may return NULL. See rule below for details. + // + // <<< For framework use only. Not for public consumption. >>> + // + /////////////////////////////////////////////////////////////////////// + template < + typename DerivedT // derived class + , typename EmbedT // how derived class is embedded + , typename T0 = nil_t // see rule class + , typename T1 = nil_t // see rule class + , typename T2 = nil_t // see rule class + > + class rule_base; // forward declaration + + class rule_base_access + { +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + public: // YUCK! +#else + template < + typename DerivedT + , typename EmbedT + , typename T0 + , typename T1 + , typename T2 + > + friend class rule_base; +#endif + template <typename RuleT> + static typename RuleT::abstract_parser_t* + get(RuleT const& r) + { + return r.get(); + } + }; + + template < + typename DerivedT // derived class + , typename EmbedT // how derived class is embedded + , typename T0 // see rule class + , typename T1 // see rule class + , typename T2 // see rule class + > + class rule_base + : public parser<DerivedT> + , public impl::get_context<T0, T1, T2>::type::base_t + , public context_aux< + typename impl::get_context<T0, T1, T2>::type, DerivedT> + , public impl::get_tag<T0, T1, T2>::type + { + public: + + typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t; + typedef typename impl::get_context<T0, T1, T2>::type context_t; + typedef typename impl::get_tag<T0, T1, T2>::type tag_t; + + typedef EmbedT embed_t; + typedef typename context_t::context_linker_t linked_context_t; + typedef typename linked_context_t::attr_t attr_t; + + template <typename ScannerT> + struct result + { + typedef typename match_result<ScannerT, attr_t>::type type; + }; + + template <typename ScannerT> + typename parser_result<DerivedT, ScannerT>::type + parse(ScannerT const& scan) const + { + typedef parser_scanner_linker<ScannerT> linked_scanner_t; + typedef typename parser_result<DerivedT, ScannerT>::type result_t; + BOOST_SPIRIT_CONTEXT_PARSE( + scan, *this, linked_scanner_t, linked_context_t, result_t); + } + + template <typename ScannerT> + typename parser_result<DerivedT, ScannerT>::type + parse_main(ScannerT const& scan) const + { + typename parser_result<DerivedT, ScannerT>::type hit; + + // MWCW 8.3 needs this cast to be done through a pointer, + // not a reference. Otherwise, it will silently construct + // a temporary, causing an infinite runtime recursion. + DerivedT const* derived_this = static_cast<DerivedT const*>(this); + + if (rule_base_access::get(*derived_this)) + { + typename ScannerT::iterator_t s(scan.first); + hit = rule_base_access::get(*derived_this) + ->do_parse_virtual(scan); + scan.group_match(hit, this->id(), s, scan.first); + } + else + { + hit = scan.no_match(); + } + return hit; + } + }; + + /////////////////////////////////////////////////////////////////////// + // + // abstract_parser class + // + /////////////////////////////////////////////////////////////////////// + template <typename ScannerT, typename AttrT> + struct abstract_parser + { + abstract_parser() {} + virtual ~abstract_parser() {} + + virtual typename match_result<ScannerT, AttrT>::type + do_parse_virtual(ScannerT const& scan) const = 0; + + virtual abstract_parser* + clone() const = 0; + }; + + /////////////////////////////////////////////////////////////////////// + // + // concrete_parser class + // + /////////////////////////////////////////////////////////////////////// +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + template <typename ParserT, typename ScannerT, typename AttrT> + struct concrete_parser : abstract_parser<ScannerT, AttrT> + { + concrete_parser(ParserT const& p_) : p(p_) {} + virtual ~concrete_parser() {} + + virtual typename match_result<ScannerT, AttrT>::type + do_parse_virtual(ScannerT const& scan) const + { + return p.parse(scan); + } + + virtual abstract_parser<ScannerT, AttrT>* + clone() const + { + return new concrete_parser(p); + } + + typename ParserT::embed_t p; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////// + // + // This generates partial specializations for the class + // + // abstract_parser + // + // with an increasing number of different ScannerT template parameters + // and corresponding do_parse_virtual function declarations for each + // of the different required scanner types: + // + // template <typename ScannerT0, ..., typename AttrT> + // struct abstract_parser<scanner_list<ScannerT0, ...>, AttrT> + // { + // abstract_parser() {} + // virtual ~abstract_parser() {} + // + // virtual typename match_result<ScannerT0, AttrT>::type + // do_parse_virtual(ScannerT0 const &scan) const = 0; + // + // virtual abstract_parser* + // clone() const = 0; + // + // ... + // }; + // + /////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _) \ + virtual typename match_result< \ + BOOST_PP_CAT(ScannerT, N), AttrT \ + >::type \ + do_parse_virtual( \ + BOOST_PP_CAT(ScannerT, N) const& scan) const = 0; \ + + #define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _) \ + template < \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \ + typename AttrT \ + > \ + struct abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + { \ + abstract_parser() {} \ + virtual ~abstract_parser() {} \ + \ + BOOST_PP_REPEAT_ ## z( \ + BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _) \ + \ + virtual abstract_parser* \ + clone() const = 0; \ + }; \ + + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _) + + #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A + #undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS + /////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////// + // + // This generates partial specializations for the class + // + // concrete_parser + // + // with an increasing number of different ScannerT template parameters + // and corresponding do_parse_virtual function declarations for each + // of the different required scanner types: + // + // template < + // typename ParserT, typename ScannerT0, ..., typename AttrT + // > + // struct concrete_parser< + // ParserT, scanner_list<ScannerT0, ...>, AttrT + // > + // : public abstract_parser<scanner_list<ScannerT0, ...>, AttrT> + // { + // concrete_parser(ParserT const& p_) : p(p_) {} + // virtual ~concrete_parser() {} + // + // virtual typename match_result<ScannerT0, AttrT>::type + // do_parse_virtual(ScannerT0 const &scan) const + // { return p.parse(scan); } + // + // virtual abstract_parser<scanner_list<ScannerT0, ...>, AttrT>* + // clone() const + // { + // return new concrete_parser(p); + // } + // + // ... + // + // typename ParserT::embed_t p; + // }; + // + /////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _) \ + virtual typename match_result< \ + BOOST_PP_CAT(ScannerT, N), AttrT \ + >::type \ + do_parse_virtual( \ + BOOST_PP_CAT(ScannerT, N) const& scan) const \ + { return p.parse(scan); } \ + + #define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _) \ + template < \ + typename ParserT, \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \ + typename AttrT \ + > \ + struct concrete_parser< \ + ParserT, \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + : abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + > \ + { \ + concrete_parser(ParserT const& p_) : p(p_) {} \ + virtual ~concrete_parser() {} \ + \ + BOOST_PP_REPEAT_ ## z( \ + BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _) \ + \ + virtual abstract_parser< \ + scanner_list< \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \ + >, \ + AttrT \ + >* \ + clone() const \ + { \ + return new concrete_parser(p); \ + } \ + \ + typename ParserT::embed_t p; \ + }; \ + + BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _) + + #undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS + #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C + /////////////////////////////////////////////////////////////////////// + +#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + } // namespace impl + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace boost::spirit + +#endif |