Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:01:55

0001 /*=============================================================================
0002     Copyright (c) 1998-2003 Joel de Guzman
0003     http://spirit.sourceforge.net/
0004 
0005   Distributed under the Boost Software License, Version 1.0. (See accompanying
0006   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #if !defined(BOOST_SPIRIT_RULE_HPP)
0009 #define BOOST_SPIRIT_RULE_HPP
0010 
0011 #include <boost/static_assert.hpp>
0012 
0013 ///////////////////////////////////////////////////////////////////////////////
0014 //
0015 //  Spirit predefined maximum number of simultaneously usable different
0016 //  scanner types.
0017 //
0018 //  This limit defines the maximum number of possible different scanner
0019 //  types for which a specific rule<> may be used. If this isn't defined, a
0020 //  rule<> may be used with one scanner type only (multiple scanner support
0021 //  is disabled).
0022 //
0023 ///////////////////////////////////////////////////////////////////////////////
0024 #if !defined(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT)
0025 #  define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 1
0026 #endif
0027 
0028 //  Ensure a meaningful maximum number of simultaneously usable scanner types
0029 BOOST_STATIC_ASSERT(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 0);
0030 
0031 #include <boost/scoped_ptr.hpp>
0032 #include <boost/spirit/home/classic/namespace.hpp>
0033 #include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp>
0034 
0035 #if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
0036 #  include <boost/preprocessor/enum_params.hpp>
0037 #endif
0038 
0039 ///////////////////////////////////////////////////////////////////////////////
0040 namespace boost { namespace spirit {
0041 
0042 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0043 
0044 #if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
0045 
0046     ///////////////////////////////////////////////////////////////////////////
0047     //
0048     //  scanner_list (a fake scanner)
0049     //
0050     //      Typically, rules are tied to a specific scanner type and
0051     //      a particular rule cannot be used with anything else. Sometimes
0052     //      there's a need for rules that can accept more than one scanner
0053     //      type. The scanner_list<S0, ...SN> can be used as a template
0054     //      parameter to the rule class to specify up to the number of
0055     //      scanner types defined by the BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT
0056     //      constant. Example:
0057     //
0058     //          rule<scanner_list<ScannerT0, ScannerT1> > r;
0059     //
0060     //      *** This feature is available only to compilers that support
0061     //      partial template specialization. ***
0062     //
0063     ///////////////////////////////////////////////////////////////////////////
0064     template <
0065         BOOST_PP_ENUM_PARAMS(
0066             BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
0067             typename ScannerT
0068         )
0069     >
0070     struct scanner_list : scanner_base {};
0071 
0072 #endif
0073 
0074     ///////////////////////////////////////////////////////////////////////////
0075     //
0076     //  rule class
0077     //
0078     //      The rule is a polymorphic parser that acts as a named place-
0079     //      holder capturing the behavior of an EBNF expression assigned to
0080     //      it.
0081     //
0082     //      The rule is a template class parameterized by:
0083     //
0084     //          1) scanner (scanner_t, see scanner.hpp),
0085     //          2) the rule's context (context_t, see parser_context.hpp)
0086     //          3) an arbitrary tag (tag_t, see parser_id.hpp) that allows
0087     //             a rule to be tagged for identification.
0088     //
0089     //      These template parameters may be specified in any order. The
0090     //      scanner will default to scanner<> when it is not specified.
0091     //      The context will default to parser_context when not specified.
0092     //      The tag will default to parser_address_tag when not specified.
0093     //
0094     //      The definition of the rule (its right hand side, RHS) held by
0095     //      the rule through a scoped_ptr. When a rule is seen in the RHS
0096     //      of an assignment or copy construction EBNF expression, the rule
0097     //      is held by the LHS rule by reference.
0098     //
0099     ///////////////////////////////////////////////////////////////////////////
0100     template <
0101         typename T0 = nil_t
0102       , typename T1 = nil_t
0103       , typename T2 = nil_t
0104     >
0105     class rule
0106         : public impl::rule_base<
0107             rule<T0, T1, T2>
0108           , rule<T0, T1, T2> const&
0109           , T0, T1, T2>
0110     {
0111     public:
0112 
0113         typedef rule<T0, T1, T2> self_t;
0114         typedef impl::rule_base<
0115             self_t
0116           , self_t const&
0117           , T0, T1, T2>
0118         base_t;
0119 
0120         typedef typename base_t::scanner_t scanner_t;
0121         typedef typename base_t::attr_t attr_t;
0122         typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t;
0123 
0124         rule() : ptr() {}
0125         ~rule() {}
0126 
0127         rule(rule const& r)
0128         : ptr(new impl::concrete_parser<rule, scanner_t, attr_t>(r)) {}
0129 
0130         template <typename ParserT>
0131         rule(ParserT const& p)
0132         : ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {}
0133 
0134         template <typename ParserT>
0135         rule& operator=(ParserT const& p)
0136         {
0137             ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p));
0138             return *this;
0139         }
0140 
0141         rule& operator=(rule const& r)
0142         {
0143             ptr.reset(new impl::concrete_parser<rule, scanner_t, attr_t>(r));
0144             return *this;
0145         }
0146 
0147         rule<T0, T1, T2>
0148         copy() const
0149         {
0150             return rule<T0, T1, T2>(ptr.get() ? ptr->clone() : 0);
0151         }
0152 
0153     private:
0154         friend class impl::rule_base_access;
0155 
0156         abstract_parser_t*
0157         get() const
0158         {
0159             return ptr.get();
0160         }
0161 
0162         rule(abstract_parser_t* ptr_)
0163         : ptr(ptr_) {}
0164 
0165         rule(abstract_parser_t const* ptr_)
0166         : ptr(ptr_) {}
0167 
0168         scoped_ptr<abstract_parser_t> ptr;
0169     };
0170 
0171 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0172 
0173 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0174 
0175 #endif