|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |