304 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			304 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================= | ||
|  |     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_SUBRULE_HPP) | ||
|  | #define BOOST_SPIRIT_SUBRULE_HPP | ||
|  | 
 | ||
|  | #include <boost/config.hpp> | ||
|  | #include <boost/static_assert.hpp> | ||
|  | #include <boost/mpl/if.hpp> | ||
|  | #include <boost/mpl/bool.hpp> | ||
|  | #include <boost/type_traits/is_same.hpp> | ||
|  | 
 | ||
|  | #include <boost/spirit/home/classic/namespace.hpp> | ||
|  | #include <boost/spirit/home/classic/core/parser.hpp> | ||
|  | #include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp> | ||
|  | 
 | ||
|  | #include <boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp> | ||
|  | #include <boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp> | ||
|  | 
 | ||
|  | namespace boost { namespace spirit { | ||
|  | 
 | ||
|  | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  subrules_scanner class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename ScannerT, typename ListT> | ||
|  |     struct subrules_scanner : public ScannerT | ||
|  |     { | ||
|  |         typedef ScannerT                            scanner_t; | ||
|  |         typedef ListT                               list_t; | ||
|  |         typedef subrules_scanner<ScannerT, ListT>   self_t; | ||
|  | 
 | ||
|  |         subrules_scanner(ScannerT const& scan, ListT const& list_) | ||
|  |         : ScannerT(scan), list(list_) {} | ||
|  | 
 | ||
|  |         template <typename PoliciesT> | ||
|  |         struct rebind_policies | ||
|  |         { | ||
|  |             typedef typename rebind_scanner_policies<ScannerT, PoliciesT>::type | ||
|  |                 rebind_scanner; | ||
|  |             typedef subrules_scanner<rebind_scanner, ListT> type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename PoliciesT> | ||
|  |         subrules_scanner< | ||
|  |             typename rebind_scanner_policies<ScannerT, PoliciesT>::type, | ||
|  |             ListT> | ||
|  |         change_policies(PoliciesT const& policies) const | ||
|  |         { | ||
|  |             typedef subrules_scanner< | ||
|  |                 BOOST_DEDUCED_TYPENAME | ||
|  |                     rebind_scanner_policies<ScannerT, PoliciesT>::type, | ||
|  |                 ListT> | ||
|  |             subrules_scanner_t; | ||
|  | 
 | ||
|  |             return subrules_scanner_t( | ||
|  |                     ScannerT::change_policies(policies), | ||
|  |                     list); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename IteratorT> | ||
|  |         struct rebind_iterator | ||
|  |         { | ||
|  |             typedef typename rebind_scanner_iterator<ScannerT, IteratorT>::type | ||
|  |                 rebind_scanner; | ||
|  |             typedef subrules_scanner<rebind_scanner, ListT> type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename IteratorT> | ||
|  |         subrules_scanner< | ||
|  |             typename rebind_scanner_iterator<ScannerT, IteratorT>::type, | ||
|  |             ListT> | ||
|  |         change_iterator(IteratorT const& first, IteratorT const &last) const | ||
|  |         { | ||
|  |             typedef subrules_scanner< | ||
|  |                 BOOST_DEDUCED_TYPENAME | ||
|  |                     rebind_scanner_iterator<ScannerT, IteratorT>::type, | ||
|  |                 ListT> | ||
|  |             subrules_scanner_t; | ||
|  | 
 | ||
|  |             return subrules_scanner_t( | ||
|  |                     ScannerT::change_iterator(first, last), | ||
|  |                     list); | ||
|  |         } | ||
|  | 
 | ||
|  |         ListT const& list; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  subrule_scanner type computer class | ||
|  |     // | ||
|  |     //      This computer ensures that the scanner will not be recursively | ||
|  |     //      instantiated if it's not needed. | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename ScannerT, typename ListT> | ||
|  |     struct subrules_scanner_finder | ||
|  |     { | ||
|  |           typedef subrules_scanner<ScannerT, ListT> type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename ScannerT, typename ListT> | ||
|  |     struct subrules_scanner_finder<subrules_scanner<ScannerT, ListT>, ListT> | ||
|  |     { | ||
|  |           typedef subrules_scanner<ScannerT, ListT> type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  subrule_list class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <typename FirstT, typename RestT> | ||
|  |     struct subrule_list : public parser<subrule_list<FirstT, RestT> > | ||
|  |     { | ||
|  |         typedef subrule_list<FirstT, RestT> self_t; | ||
|  |         typedef FirstT                      first_t; | ||
|  |         typedef RestT                       rest_t; | ||
|  | 
 | ||
|  |         subrule_list(FirstT const& first_, RestT const& rest_) | ||
|  |         : first(first_), rest(rest_) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename parser_result<FirstT, ScannerT>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename subrules_scanner_finder<ScannerT, self_t>::type | ||
|  |             subrules_scanner_t; | ||
|  |             subrules_scanner_t g_arg(scan, *this); | ||
|  |             return first.start.parse(g_arg); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <int ID, typename DefT, typename ContextT> | ||
|  |         subrule_list< | ||
|  |             FirstT, | ||
|  |             subrule_list< | ||
|  |                 subrule_parser<ID, DefT, ContextT>, | ||
|  |                 RestT> > | ||
|  |         operator,(subrule_parser<ID, DefT, ContextT> const& rhs_) | ||
|  |         { | ||
|  |             return subrule_list< | ||
|  |                 FirstT, | ||
|  |                 subrule_list< | ||
|  |                     subrule_parser<ID, DefT, ContextT>, | ||
|  |                     RestT> >( | ||
|  |                         first, | ||
|  |                         subrule_list< | ||
|  |                             subrule_parser<ID, DefT, ContextT>, | ||
|  |                             RestT>(rhs_, rest)); | ||
|  |         } | ||
|  | 
 | ||
|  |         FirstT first; | ||
|  |         RestT rest; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  subrule_parser class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <int ID, typename DefT, typename ContextT> | ||
|  |     struct subrule_parser | ||
|  |     : public parser<subrule_parser<ID, DefT, ContextT> > | ||
|  |     { | ||
|  |         typedef subrule_parser<ID, DefT, ContextT> self_t; | ||
|  |         typedef subrule<ID, ContextT> subrule_t; | ||
|  |         typedef DefT def_t; | ||
|  | 
 | ||
|  |         BOOST_STATIC_CONSTANT(int, id = ID); | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename | ||
|  |                 impl::get_subrule_parser_result< | ||
|  |                     DefT, ScannerT, typename subrule_t::attr_t>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         subrule_parser(subrule_t const& start_, DefT const& rhs_) | ||
|  |         : rhs(rhs_), start(start_) {} | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             // This will only be called when parsing single subrules. | ||
|  |             typedef subrule_list<self_t, nil_t> list_t; | ||
|  |             typedef subrules_scanner<ScannerT, list_t> scanner_t; | ||
|  | 
 | ||
|  |             list_t    list(*this, nil_t()); | ||
|  |             scanner_t g_arg(scan, list); | ||
|  |             return start.parse(g_arg); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <int ID2, typename DefT2, typename ContextT2> | ||
|  |         inline subrule_list< | ||
|  |             self_t, | ||
|  |             subrule_list< | ||
|  |                 subrule_parser<ID2, DefT2, ContextT2>, | ||
|  |                 nil_t> > | ||
|  |         operator,(subrule_parser<ID2, DefT2, ContextT2> const& rhs) const | ||
|  |         { | ||
|  |             return subrule_list< | ||
|  |                 self_t, | ||
|  |                 subrule_list< | ||
|  |                     subrule_parser<ID2, DefT2, ContextT2>, | ||
|  |                     nil_t> >( | ||
|  |                         *this, | ||
|  |                         subrule_list< | ||
|  |                             subrule_parser<ID2, DefT2, ContextT2>, nil_t>( | ||
|  |                                 rhs, nil_t())); | ||
|  |         } | ||
|  | 
 | ||
|  |         typename DefT::embed_t rhs; | ||
|  |         subrule_t const& start; | ||
|  |     }; | ||
|  | 
 | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     // | ||
|  |     //  subrule class | ||
|  |     // | ||
|  |     /////////////////////////////////////////////////////////////////////////// | ||
|  |     template <int ID, typename ContextT> | ||
|  |     struct subrule | ||
|  |         : public parser<subrule<ID, ContextT> > | ||
|  |         , public ContextT::base_t | ||
|  |         , public context_aux<ContextT, subrule<ID, ContextT> > | ||
|  |     { | ||
|  |         typedef subrule<ID, ContextT> self_t; | ||
|  |         typedef subrule<ID, ContextT> const&  embed_t; | ||
|  | 
 | ||
|  |         typedef typename ContextT::context_linker_t context_t; | ||
|  |         typedef typename context_t::attr_t attr_t; | ||
|  | 
 | ||
|  |         BOOST_STATIC_CONSTANT(int, id = ID); | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         struct result | ||
|  |         { | ||
|  |             typedef typename | ||
|  |                 impl::get_subrule_result<ID, ScannerT, attr_t>::type type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse_main(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             result_t result_; | ||
|  |             impl::parse_subrule<result_t, ScannerT, ID>:: | ||
|  |                 do_(result_, scan); | ||
|  |             return result_; | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename ScannerT> | ||
|  |         typename parser_result<self_t, ScannerT>::type | ||
|  |         parse(ScannerT const& scan) const | ||
|  |         { | ||
|  |             typedef typename parser_result<self_t, ScannerT>::type result_t; | ||
|  |             typedef parser_scanner_linker<ScannerT> scanner_t; | ||
|  |             BOOST_SPIRIT_CONTEXT_PARSE( | ||
|  |                 scan, *this, scanner_t, context_t, result_t); | ||
|  |         } | ||
|  | 
 | ||
|  |         template <typename DefT> | ||
|  |         subrule_parser<ID, DefT, ContextT> | ||
|  |         operator=(parser<DefT> const& rhs) const | ||
|  |         { | ||
|  |             return subrule_parser<ID, DefT, ContextT>(*this, rhs.derived()); | ||
|  |         } | ||
|  | 
 | ||
|  |     private: | ||
|  | 
 | ||
|  |         //  assignment of subrules is not allowed. Use subrules | ||
|  |         //  with identical IDs if you want to have aliases. | ||
|  | 
 | ||
|  |         subrule& operator=(subrule const&); | ||
|  | 
 | ||
|  |         template <int ID2, typename ContextT2> | ||
|  |         subrule& operator=(subrule<ID2, ContextT2> const&); | ||
|  |     }; | ||
|  | 
 | ||
|  | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | ||
|  | 
 | ||
|  | }} // namespace BOOST_SPIRIT_CLASSIC_NS | ||
|  | 
 | ||
|  | #endif | ||
|  | 
 |