Line data Source code
1 : /*============================================================================= 2 : Copyright (c) 2002-2003 Joel de Guzman 3 : Copyright (c) 2002-2003 Hartmut Kaiser 4 : http://spirit.sourceforge.net/ 5 : 6 : Distributed under the Boost Software License, Version 1.0. (See accompanying 7 : file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 : =============================================================================*/ 9 : #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_HPP) 10 : #define BOOST_SPIRIT_PARSER_CONTEXT_HPP 11 : 12 : /////////////////////////////////////////////////////////////////////////////// 13 : namespace boost 14 : { 15 : namespace spirit 16 : { 17 : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 18 : 19 : 20 : /////////////////////////////////////////////////////////////////////////// 21 : // 22 : // default_parser_context_base class { default context base } 23 : // 24 : /////////////////////////////////////////////////////////////////////////// 25 : struct default_parser_context_base 26 : { 27 : template <typename DerivedT> 28 : struct aux {}; 29 : }; 30 : 31 : /////////////////////////////////////////////////////////////////////////// 32 : // 33 : // parser_context_base class { base class of all context classes } 34 : // 35 : /////////////////////////////////////////////////////////////////////////// 36 : struct parser_context_base {}; 37 : 38 : /////////////////////////////////////////////////////////////////////////// 39 : // 40 : // parser_context class { default context } 41 : // 42 : /////////////////////////////////////////////////////////////////////////// 43 : struct nil_t; 44 : template<typename ContextT> struct parser_context_linker; 45 : 46 : template<typename AttrT = nil_t> 47 : struct parser_context : parser_context_base 48 : { 49 : typedef AttrT attr_t; 50 : typedef default_parser_context_base base_t; 51 : typedef parser_context_linker<parser_context<AttrT> > context_linker_t; 52 : 53 : template <typename ParserT> 54 0 : parser_context(ParserT const&) {} 55 : 56 : template <typename ParserT, typename ScannerT> 57 : void 58 0 : pre_parse(ParserT const&, ScannerT const&) {} 59 : 60 : template <typename ResultT, typename ParserT, typename ScannerT> 61 : ResultT& 62 0 : post_parse(ResultT& hit, ParserT const&, ScannerT const&) 63 : { return hit; } 64 : }; 65 : 66 : /////////////////////////////////////////////////////////////////////////// 67 : // 68 : // context_aux class 69 : // 70 : // context_aux<ContextT, DerivedT> is a class derived from the 71 : // ContextT's nested base_t::base<DerivedT> template class. (see 72 : // default_parser_context_base::aux for an example). 73 : // 74 : // Basically, this class provides ContextT dependent optional 75 : // functionality to the derived class DerivedT through the CRTP 76 : // idiom (Curiously recurring template pattern). 77 : // 78 : /////////////////////////////////////////////////////////////////////////// 79 : template <typename ContextT, typename DerivedT> 80 : struct context_aux : public ContextT::base_t::template aux<DerivedT> {}; 81 : 82 : /////////////////////////////////////////////////////////////////////////// 83 : // 84 : // parser_scanner_linker and parser_scanner_linker classes 85 : // { helper templates for the rule extensibility } 86 : // 87 : // This classes can be 'overloaded' (defined elsewhere), to plug 88 : // in additional functionality into the non-terminal parsing process. 89 : // 90 : /////////////////////////////////////////////////////////////////////////// 91 : #if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) 92 : #define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED 93 : 94 : template<typename ScannerT> 95 : struct parser_scanner_linker : public ScannerT 96 : { 97 0 : parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {} 98 : }; 99 : 100 : #endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED) 101 : 102 : ////////////////////////////////// 103 : #if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) 104 : #define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED 105 : 106 : template<typename ContextT> 107 : struct parser_context_linker : public ContextT 108 : { 109 : template <typename ParserT> 110 0 : parser_context_linker(ParserT const& p) 111 0 : : ContextT(p) {} 112 : 113 : template <typename ParserT, typename ScannerT> 114 0 : void pre_parse(ParserT const& p, ScannerT const& scan) 115 0 : { ContextT::pre_parse(p, scan); } 116 : 117 : template <typename ResultT, typename ParserT, typename ScannerT> 118 : ResultT& 119 0 : post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan) 120 0 : { return ContextT::post_parse(hit, p, scan); } 121 : }; 122 : 123 : #endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED) 124 : 125 : /////////////////////////////////////////////////////////////////////////// 126 : // 127 : // BOOST_SPIRIT_CONTEXT_PARSE helper macro 128 : // 129 : // The original implementation uses a template class. However, we 130 : // need to lessen the template instantiation depth to help inferior 131 : // compilers that sometimes choke on deep template instantiations. 132 : // The objective is to avoid code redundancy. A macro, in this case 133 : // is an obvious solution. Sigh! 134 : // 135 : // WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION. 136 : // 137 : /////////////////////////////////////////////////////////////////////////// 138 : #define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \ 139 : scanner_t scan_wrap(scan); \ 140 : context_t context_wrap(this_); \ 141 : context_wrap.pre_parse(this_, scan_wrap); \ 142 : result_t hit = parse_main(scan); \ 143 : return context_wrap.post_parse(hit, this_, scan_wrap); 144 : 145 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END 146 : 147 : } // namespace spirit 148 : } // namespace boost 149 : 150 : #endif