diff options
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal')
4 files changed, 867 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 diff --git a/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/parser_context.hpp b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/parser_context.hpp new file mode 100644 index 0000000..2f7dd23 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/parser_context.hpp @@ -0,0 +1,150 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + Copyright (c) 2002-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + 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_PARSER_CONTEXT_HPP) +#define BOOST_SPIRIT_PARSER_CONTEXT_HPP + +/////////////////////////////////////////////////////////////////////////////// +namespace boost +{ + namespace spirit + { + BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + + /////////////////////////////////////////////////////////////////////////// + // + // default_parser_context_base class { default context base } + // + /////////////////////////////////////////////////////////////////////////// + struct default_parser_context_base + { + template <typename DerivedT> + struct aux {}; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context_base class { base class of all context classes } + // + /////////////////////////////////////////////////////////////////////////// + struct parser_context_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_context class { default context } + // + /////////////////////////////////////////////////////////////////////////// + struct nil_t; + template<typename ContextT> struct parser_context_linker; + + template<typename AttrT = nil_t> + struct parser_context : parser_context_base + { + typedef AttrT attr_t; + typedef default_parser_context_base base_t; + typedef parser_context_linker<parser_context<AttrT> > context_linker_t; + + template <typename ParserT> + parser_context(ParserT const&) {} + + template <typename ParserT, typename ScannerT> + void + pre_parse(ParserT const&, ScannerT const&) {} + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& + post_parse(ResultT& hit, ParserT const&, ScannerT const&) + { return hit; } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // context_aux class + // + // context_aux<ContextT, DerivedT> is a class derived from the + // ContextT's nested base_t::base<DerivedT> template class. (see + // default_parser_context_base::aux for an example). + // + // Basically, this class provides ContextT dependent optional + // functionality to the derived class DerivedT through the CRTP + // idiom (Curiously recurring template pattern). + // + /////////////////////////////////////////////////////////////////////////// + template <typename ContextT, typename DerivedT> + struct context_aux : public ContextT::base_t::template aux<DerivedT> {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_scanner_linker and parser_scanner_linker classes + // { helper templates for the rule extensibility } + // + // This classes can be 'overloaded' (defined elsewhere), to plug + // in additional functionality into the non-terminal parsing process. + // + /////////////////////////////////////////////////////////////////////////// + #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED + + template<typename ScannerT> + struct parser_scanner_linker : public ScannerT + { + parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {} + }; + + #endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) + + ////////////////////////////////// + #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED + + template<typename ContextT> + struct parser_context_linker : public ContextT + { + template <typename ParserT> + parser_context_linker(ParserT const& p) + : ContextT(p) {} + + template <typename ParserT, typename ScannerT> + void pre_parse(ParserT const& p, ScannerT const& scan) + { ContextT::pre_parse(p, scan); } + + template <typename ResultT, typename ParserT, typename ScannerT> + ResultT& + post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan) + { return ContextT::post_parse(hit, p, scan); } + }; + + #endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) + + /////////////////////////////////////////////////////////////////////////// + // + // BOOST_SPIRIT_CONTEXT_PARSE helper macro + // + // The original implementation uses a template class. However, we + // need to lessen the template instantiation depth to help inferior + // compilers that sometimes choke on deep template instantiations. + // The objective is to avoid code redundancy. A macro, in this case + // is an obvious solution. Sigh! + // + // WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION. + // + /////////////////////////////////////////////////////////////////////////// + #define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \ + scanner_t scan_wrap(scan); \ + context_t context_wrap(this_); \ + context_wrap.pre_parse(this_, scan_wrap); \ + result_t hit = parse_main(scan); \ + return context_wrap.post_parse(hit, this_, scan_wrap); + + BOOST_SPIRIT_CLASSIC_NAMESPACE_END + + } // namespace spirit +} // namespace boost + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/parser_id.hpp b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/parser_id.hpp new file mode 100644 index 0000000..bc465dc --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/parser_id.hpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2001-2003 Joel de Guzman + Copyright (c) 2001 Daniel Nuffer + http://spirit.sourceforge.net/ + + 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_PARSER_ID_HPP) +#define BOOST_SPIRIT_PARSER_ID_HPP + +#if defined(BOOST_SPIRIT_DEBUG) +# include <ostream> +#endif +#include <boost/spirit/home/classic/namespace.hpp> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + + /////////////////////////////////////////////////////////////////////////// + // + // parser_id class + // + /////////////////////////////////////////////////////////////////////////// + class parser_id + { + public: + parser_id() : p(0) {} + explicit parser_id(void const* prule) : p(prule) {} + parser_id(std::size_t l_) : l(l_) {} + + bool operator==(parser_id const& x) const { return p == x.p; } + bool operator!=(parser_id const& x) const { return !(*this == x); } + bool operator<(parser_id const& x) const { return p < x.p; } + std::size_t to_long() const { return l; } + + private: + + union + { + void const* p; + std::size_t l; + }; + }; + + #if defined(BOOST_SPIRIT_DEBUG) + inline std::ostream& + operator<<(std::ostream& out, parser_id const& rid) + { + out << (unsigned int)rid.to_long(); + return out; + } + #endif + + /////////////////////////////////////////////////////////////////////////// + // + // parser_tag_base class: base class of all parser tags + // + /////////////////////////////////////////////////////////////////////////// + struct parser_tag_base {}; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_address_tag class: tags a parser with its address + // + /////////////////////////////////////////////////////////////////////////// + struct parser_address_tag : parser_tag_base + { + parser_id id() const + { return parser_id(reinterpret_cast<std::size_t>(this)); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // parser_tag class: tags a parser with an integer ID + // + /////////////////////////////////////////////////////////////////////////// + template <int N> + struct parser_tag : parser_tag_base + { + static parser_id id() + { return parser_id(std::size_t(N)); } + }; + + /////////////////////////////////////////////////////////////////////////// + // + // dynamic_parser_tag class: tags a parser with a dynamically changeable + // integer ID + // + /////////////////////////////////////////////////////////////////////////// + class dynamic_parser_tag : public parser_tag_base + { + public: + + dynamic_parser_tag() + : tag(std::size_t(0)) {} + + parser_id + id() const + { + return + tag.to_long() + ? tag + : parser_id(reinterpret_cast<std::size_t>(this)); + } + + void set_id(parser_id id_) { tag = id_; } + + private: + + parser_id tag; + }; + +/////////////////////////////////////////////////////////////////////////////// +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif + diff --git a/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/rule.hpp b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/rule.hpp new file mode 100644 index 0000000..e905689 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/classic/core/non_terminal/rule.hpp @@ -0,0 +1,175 @@ +/*============================================================================= + Copyright (c) 1998-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + 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_RULE_HPP) +#define BOOST_SPIRIT_RULE_HPP + +#include <boost/static_assert.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// +// Spirit predefined maximum number of simultaneously usable different +// scanner types. +// +// This limit defines the maximum number of of possible different scanner +// types for which a specific rule<> may be used. If this isn't defined, a +// rule<> may be used with one scanner type only (multiple scanner support +// is disabled). +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT) +# define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 1 +#endif + +// Ensure a meaningful maximum number of simultaneously usable scanner types +BOOST_STATIC_ASSERT(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 0); + +#include <boost/scoped_ptr.hpp> +#include <boost/spirit/home/classic/namespace.hpp> +#include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp> + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 +# include <boost/preprocessor/enum_params.hpp> +#endif + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { + +BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN + +#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1 + + /////////////////////////////////////////////////////////////////////////// + // + // scanner_list (a fake scanner) + // + // Typically, rules are tied to a specific scanner type and + // a particular rule cannot be used with anything else. Sometimes + // there's a need for rules that can accept more than one scanner + // type. The scanner_list<S0, ...SN> can be used as a template + // parameter to the rule class to specify up to the number of + // scanner types defined by the BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT + // constant. Example: + // + // rule<scanner_list<ScannerT0, ScannerT1> > r; + // + // *** This feature is available only to compilers that support + // partial template specialization. *** + // + /////////////////////////////////////////////////////////////////////////// + template < + BOOST_PP_ENUM_PARAMS( + BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT, + typename ScannerT + ) + > + struct scanner_list : scanner_base {}; + +#endif + + /////////////////////////////////////////////////////////////////////////// + // + // rule class + // + // The rule is a polymorphic parser that acts as a named place- + // holder capturing the behavior of an EBNF expression assigned to + // it. + // + // The rule is a template class parameterized by: + // + // 1) scanner (scanner_t, see scanner.hpp), + // 2) the rule's context (context_t, see parser_context.hpp) + // 3) an arbitrary tag (tag_t, see parser_id.hpp) that allows + // a rule to be tagged for identification. + // + // These template parameters may be specified in any order. The + // scanner will default to scanner<> when it is not specified. + // The context will default to parser_context when not specified. + // The tag will default to parser_address_tag when not specified. + // + // The definition of the rule (its right hand side, RHS) held by + // the rule through a scoped_ptr. When a rule is seen in the RHS + // of an assignment or copy construction EBNF expression, the rule + // is held by the LHS rule by reference. + // + /////////////////////////////////////////////////////////////////////////// + template < + typename T0 = nil_t + , typename T1 = nil_t + , typename T2 = nil_t + > + class rule + : public impl::rule_base< + rule<T0, T1, T2> + , rule<T0, T1, T2> const& + , T0, T1, T2> + { + public: + + typedef rule<T0, T1, T2> self_t; + typedef impl::rule_base< + self_t + , self_t const& + , T0, T1, T2> + base_t; + + typedef typename base_t::scanner_t scanner_t; + typedef typename base_t::attr_t attr_t; + typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t; + + rule() : ptr() {} + ~rule() {} + + rule(rule const& r) + : ptr(new impl::concrete_parser<rule, scanner_t, attr_t>(r)) {} + + template <typename ParserT> + rule(ParserT const& p) + : ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {} + + template <typename ParserT> + rule& operator=(ParserT const& p) + { + ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)); + return *this; + } + + rule& operator=(rule const& r) + { + ptr.reset(new impl::concrete_parser<rule, scanner_t, attr_t>(r)); + return *this; + } + + rule<T0, T1, T2> + copy() const + { + return rule<T0, T1, T2>(ptr.get() ? ptr->clone() : 0); + } + + private: + friend class impl::rule_base_access; + + abstract_parser_t* + get() const + { + return ptr.get(); + } + + rule(abstract_parser_t* ptr_) + : ptr(ptr_) {} + + rule(abstract_parser_t const* ptr_) + : ptr(ptr_) {} + + scoped_ptr<abstract_parser_t> ptr; + }; + +BOOST_SPIRIT_CLASSIC_NAMESPACE_END + +}} // namespace BOOST_SPIRIT_CLASSIC_NS + +#endif |