LCOV - code coverage report
Current view: top level - usr/include/boost/spirit/home/classic/core/non_terminal/impl - rule.ipp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 19 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*=============================================================================
       2             :     Copyright (c) 1998-2003 Joel de Guzman
       3             :     http://spirit.sourceforge.net/
       4             : 
       5             :     Use, modification and distribution is subject to the Boost Software
       6             :     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       7             :     http://www.boost.org/LICENSE_1_0.txt)
       8             : =============================================================================*/
       9             : #if !defined(BOOST_SPIRIT_RULE_IPP)
      10             : #define BOOST_SPIRIT_RULE_IPP
      11             : 
      12             : #if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
      13             : #include <boost/preprocessor/repeat.hpp>
      14             : #include <boost/preprocessor/repeat_from_to.hpp>
      15             : #include <boost/preprocessor/enum_params.hpp>
      16             : #include <boost/preprocessor/enum_params_with_defaults.hpp>
      17             : #include <boost/preprocessor/facilities/intercept.hpp>
      18             : #include <boost/preprocessor/inc.hpp>
      19             : #include <boost/preprocessor/cat.hpp>
      20             : #endif
      21             : 
      22             : #include <boost/spirit/home/classic/core/parser.hpp>
      23             : #include <boost/spirit/home/classic/core/scanner/scanner.hpp>
      24             : #include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
      25             : #include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp>
      26             : #include <boost/type_traits/is_base_and_derived.hpp>
      27             : #include <boost/mpl/if.hpp>
      28             : 
      29             : ///////////////////////////////////////////////////////////////////////////////
      30             : namespace boost { namespace spirit {
      31             : 
      32             : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
      33             : 
      34             : #if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
      35             : 
      36             :         template <
      37             :             BOOST_PP_ENUM_BINARY_PARAMS(
      38             :                 BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
      39             :                 typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT
      40             :             )
      41             :         >
      42             :         struct scanner_list;
      43             : 
      44             : #endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
      45             : 
      46             :     ///////////////////////////////////////////////////////////////////////////
      47             :     namespace impl
      48             :     {
      49             :         template <typename BaseT, typename DefaultT
      50             :             , typename T0, typename T1, typename T2>
      51             :         struct get_param
      52             :         {
      53             :             typedef typename mpl::if_<
      54             :                 is_base_and_derived<BaseT, T0>
      55             :               , T0
      56             :               , typename mpl::if_<
      57             :                     is_base_and_derived<BaseT, T1>
      58             :                   , T1
      59             :                   , typename mpl::if_<
      60             :                         is_base_and_derived<BaseT, T2>
      61             :                       , T2
      62             :                       , DefaultT
      63             :                     >::type
      64             :                 >::type
      65             :             >::type type;
      66             :         };
      67             : 
      68             :         template <typename T0, typename T1, typename T2>
      69             :         struct get_context
      70             :         {
      71             :             typedef typename get_param<
      72             :                 parser_context_base, parser_context<>, T0, T1, T2>::type
      73             :             type;
      74             :         };
      75             : 
      76             :         template <typename T0, typename T1, typename T2>
      77             :         struct get_tag
      78             :         {
      79             :             typedef typename get_param<
      80             :                 parser_tag_base, parser_address_tag, T0, T1, T2>::type
      81             :             type;
      82             :         };
      83             : 
      84             :         template <typename T0, typename T1, typename T2>
      85             :         struct get_scanner
      86             :         {
      87             :             typedef typename get_param<
      88             :                 scanner_base, scanner<>, T0, T1, T2>::type
      89             :             type;
      90             :         };
      91             : 
      92             :         ///////////////////////////////////////////////////////////////////////
      93             :         //
      94             :         //  rule_base class
      95             :         //
      96             :         //      The rule_base class implements the basic plumbing for rules
      97             :         //      minus the storage mechanism. It is up to the derived class
      98             :         //      to actually store the definition somewhere. The rule_base
      99             :         //      class assumes that the derived class provides a get() function
     100             :         //      that will return a pointer to a parser. The get() function
     101             :         //      may return NULL. See rule below for details.
     102             :         //
     103             :         //      <<< For framework use only. Not for public consumption. >>>
     104             :         //
     105             :         ///////////////////////////////////////////////////////////////////////
     106             :         template <
     107             :             typename DerivedT       // derived class
     108             :           , typename EmbedT         // how derived class is embedded
     109             :           , typename T0 = nil_t     // see rule class
     110             :           , typename T1 = nil_t     // see rule class
     111             :           , typename T2 = nil_t     // see rule class
     112             :         >
     113             :         class rule_base; // forward declaration
     114             : 
     115             :         class rule_base_access
     116             :         {
     117             : #if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
     118             :     || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
     119             :         public: // YUCK!
     120             : #else
     121             :             template <
     122             :                 typename DerivedT
     123             :               , typename EmbedT
     124             :               , typename T0
     125             :               , typename T1
     126             :               , typename T2
     127             :             >
     128             :            friend class rule_base;
     129             : #endif
     130             :             template <typename RuleT>
     131             :             static typename RuleT::abstract_parser_t*
     132           0 :             get(RuleT const& r)
     133             :             {
     134           0 :                 return r.get();
     135             :             }
     136             :         };
     137             : 
     138             :         template <
     139             :             typename DerivedT       // derived class
     140             :           , typename EmbedT         // how derived class is embedded
     141             :           , typename T0             // see rule class
     142             :           , typename T1             // see rule class
     143             :           , typename T2             // see rule class
     144             :         >
     145             :         class rule_base
     146             :             : public parser<DerivedT>
     147             :             , public impl::get_context<T0, T1, T2>::type::base_t
     148             :             , public context_aux<
     149             :                 typename impl::get_context<T0, T1, T2>::type, DerivedT>
     150             :             , public impl::get_tag<T0, T1, T2>::type
     151             :         {
     152             :         public:
     153             : 
     154             :             typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t;
     155             :             typedef typename impl::get_context<T0, T1, T2>::type context_t;
     156             :             typedef typename impl::get_tag<T0, T1, T2>::type tag_t;
     157             : 
     158             :             typedef EmbedT embed_t;
     159             :             typedef typename context_t::context_linker_t linked_context_t;
     160             :             typedef typename linked_context_t::attr_t attr_t;
     161             : 
     162             :             template <typename ScannerT>
     163             :             struct result
     164             :             {
     165             :                 typedef typename match_result<ScannerT, attr_t>::type type;
     166             :             };
     167             : 
     168             :             template <typename ScannerT>
     169             :             typename parser_result<DerivedT, ScannerT>::type
     170           0 :             parse(ScannerT const& scan) const
     171             :             {
     172             :                 typedef parser_scanner_linker<ScannerT> linked_scanner_t;
     173             :                 typedef typename parser_result<DerivedT, ScannerT>::type result_t;
     174           0 :                 BOOST_SPIRIT_CONTEXT_PARSE(
     175             :                     scan, *this, linked_scanner_t, linked_context_t, result_t);
     176             :             }
     177             : 
     178             :             template <typename ScannerT>
     179             :             typename parser_result<DerivedT, ScannerT>::type
     180           0 :             parse_main(ScannerT const& scan) const
     181             :             {
     182           0 :                 typename parser_result<DerivedT, ScannerT>::type hit;
     183             : 
     184             :                 //  MWCW 8.3 needs this cast to be done through a pointer,
     185             :                 //  not a reference. Otherwise, it will silently construct
     186             :                 //  a temporary, causing an infinite runtime recursion.
     187           0 :                 DerivedT const* derived_this = static_cast<DerivedT const*>(this);
     188             : 
     189           0 :                 if (rule_base_access::get(*derived_this))
     190             :                 {
     191           0 :                     typename ScannerT::iterator_t s(scan.first);
     192           0 :                     hit = rule_base_access::get(*derived_this)
     193             :                             ->do_parse_virtual(scan);
     194           0 :                     scan.group_match(hit, this->id(), s, scan.first);
     195             :                 }
     196             :                 else
     197             :                 {
     198             :                     hit = scan.no_match();
     199             :                 }
     200             :                 return hit;
     201             :             }
     202             :         };
     203             : 
     204             :         ///////////////////////////////////////////////////////////////////////
     205             :         //
     206             :         //  abstract_parser class
     207             :         //
     208             :         ///////////////////////////////////////////////////////////////////////
     209             :         template <typename ScannerT, typename AttrT>
     210             :         struct abstract_parser
     211             :         {
     212           0 :             abstract_parser() {}
     213           0 :             virtual ~abstract_parser() {}
     214             : 
     215             :             virtual typename match_result<ScannerT, AttrT>::type
     216             :             do_parse_virtual(ScannerT const& scan) const = 0;
     217             : 
     218             :             virtual abstract_parser*
     219             :             clone() const = 0;
     220             :         };
     221             : 
     222             :         ///////////////////////////////////////////////////////////////////////
     223             :         //
     224             :         //  concrete_parser class
     225             :         //
     226             :         ///////////////////////////////////////////////////////////////////////
     227             : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
     228             : #pragma warning(push)
     229             : #pragma warning(disable:4512) //assignment operator could not be generated
     230             : #endif
     231             :         
     232             :         template <typename ParserT, typename ScannerT, typename AttrT>
     233             :         struct concrete_parser : abstract_parser<ScannerT, AttrT>
     234             :         {
     235           0 :             concrete_parser(ParserT const& p_) : p(p_) {}
     236           0 :             virtual ~concrete_parser() {}
     237             : 
     238             :             virtual typename match_result<ScannerT, AttrT>::type
     239           0 :             do_parse_virtual(ScannerT const& scan) const
     240             :             {
     241           0 :                 return p.parse(scan);
     242             :             }
     243             : 
     244             :             virtual abstract_parser<ScannerT, AttrT>*
     245           0 :             clone() const
     246             :             {
     247           0 :                 return new concrete_parser(p);
     248             :             }
     249             : 
     250             :             typename ParserT::embed_t p;
     251             :         };
     252             :         
     253             : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
     254             : #pragma warning(pop)
     255             : #endif
     256             : 
     257             : #if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
     258             : 
     259             :         ///////////////////////////////////////////////////////////////////////
     260             :         //
     261             :         //  This generates partial specializations for the class
     262             :         //
     263             :         //          abstract_parser
     264             :         //
     265             :         //  with an increasing number of different ScannerT template parameters
     266             :         //  and corresponding do_parse_virtual function declarations for each
     267             :         //  of the different required scanner types:
     268             :         //
     269             :         //      template <typename ScannerT0, ..., typename AttrT>
     270             :         //      struct abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
     271             :         //      {
     272             :         //          abstract_parser() {}
     273             :         //          virtual ~abstract_parser() {}
     274             :         //
     275             :         //          virtual typename match_result<ScannerT0, AttrT>::type
     276             :         //          do_parse_virtual(ScannerT0 const &scan) const = 0;
     277             :         //
     278             :         //          virtual abstract_parser*
     279             :         //          clone() const = 0;
     280             :         //
     281             :         //          ...
     282             :         //      };
     283             :         //
     284             :         ///////////////////////////////////////////////////////////////////////
     285             :         #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _)                       \
     286             :                 virtual typename match_result<                                  \
     287             :                     BOOST_PP_CAT(ScannerT, N), AttrT                            \
     288             :                 >::type                                                         \
     289             :                 do_parse_virtual(                                               \
     290             :                     BOOST_PP_CAT(ScannerT, N) const& scan) const = 0;           \
     291             : 
     292             :         #define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _)                     \
     293             :             template <                                                          \
     294             :                 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT),  \
     295             :                 typename AttrT                                                  \
     296             :             >                                                                   \
     297             :             struct abstract_parser<                                             \
     298             :                 scanner_list<                                                   \
     299             :                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT)        \
     300             :                 >,                                                              \
     301             :                 AttrT                                                           \
     302             :             >                                                                   \
     303             :             {                                                                   \
     304             :                 abstract_parser() {}                                            \
     305             :                 virtual ~abstract_parser() {}                                   \
     306             :                                                                                 \
     307             :                 BOOST_PP_REPEAT_ ## z(                                          \
     308             :                     BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _)       \
     309             :                                                                                 \
     310             :                 virtual abstract_parser*                                        \
     311             :                 clone() const = 0;                                              \
     312             :             };                                                                  \
     313             : 
     314             :         BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
     315             :             BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _)
     316             : 
     317             :         #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A
     318             :         #undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS
     319             :         ///////////////////////////////////////////////////////////////////////
     320             : 
     321             :         ///////////////////////////////////////////////////////////////////////
     322             :         //
     323             :         //  This generates partial specializations for the class
     324             :         //
     325             :         //          concrete_parser
     326             :         //
     327             :         //  with an increasing number of different ScannerT template parameters
     328             :         //  and corresponding do_parse_virtual function declarations for each
     329             :         //  of the different required scanner types:
     330             :         //
     331             :         //      template <
     332             :         //          typename ParserT, typename ScannerT0, ..., typename AttrT
     333             :         //      >
     334             :         //      struct concrete_parser<
     335             :         //          ParserT, scanner_list<ScannerT0, ...>, AttrT
     336             :         //      >
     337             :         //      :   public abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
     338             :         //      {
     339             :         //          concrete_parser(ParserT const& p_) : p(p_) {}
     340             :         //          virtual ~concrete_parser() {}
     341             :         //
     342             :         //          virtual typename match_result<ScannerT0, AttrT>::type
     343             :         //          do_parse_virtual(ScannerT0 const &scan) const
     344             :         //          { return p.parse(scan); }
     345             :         //
     346             :         //          virtual abstract_parser<scanner_list<ScannerT0, ...>, AttrT>*
     347             :         //          clone() const
     348             :         //          {
     349             :         //              return new concrete_parser(p);
     350             :         //          }
     351             :         //
     352             :         //          ...
     353             :         //
     354             :         //          typename ParserT::embed_t p;
     355             :         //      };
     356             :         //
     357             :         ///////////////////////////////////////////////////////////////////////
     358             :         #define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _)                       \
     359             :                 virtual typename match_result<                                  \
     360             :                     BOOST_PP_CAT(ScannerT, N), AttrT                            \
     361             :                 >::type                                                         \
     362             :                 do_parse_virtual(                                               \
     363             :                     BOOST_PP_CAT(ScannerT, N) const& scan) const                \
     364             :                 { return p.parse(scan); }                                       \
     365             : 
     366             :         #define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _)                     \
     367             :             template <                                                          \
     368             :                 typename ParserT,                                               \
     369             :                 BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT),  \
     370             :                 typename AttrT                                                  \
     371             :             >                                                                   \
     372             :             struct concrete_parser<                                             \
     373             :                 ParserT,                                                        \
     374             :                 scanner_list<                                                   \
     375             :                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT)        \
     376             :                 >,                                                              \
     377             :                 AttrT                                                           \
     378             :             >                                                                   \
     379             :             :   abstract_parser<                                                \
     380             :                     scanner_list<                                               \
     381             :                         BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT)    \
     382             :                     >,                                                          \
     383             :                     AttrT                                                       \
     384             :                 >                                                               \
     385             :             {                                                                   \
     386             :                 concrete_parser(ParserT const& p_) : p(p_) {}                   \
     387             :                 virtual ~concrete_parser() {}                                   \
     388             :                                                                                 \
     389             :                 BOOST_PP_REPEAT_ ## z(                                          \
     390             :                     BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _)       \
     391             :                                                                                 \
     392             :                 virtual abstract_parser<                                        \
     393             :                     scanner_list<                                               \
     394             :                         BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT)    \
     395             :                     >,                                                          \
     396             :                     AttrT                                                       \
     397             :                 >*                                                              \
     398             :                 clone() const                                                   \
     399             :                 {                                                               \
     400             :                     return new concrete_parser(p);                              \
     401             :                 }                                                               \
     402             :                                                                                 \
     403             :                 typename ParserT::embed_t p;                                    \
     404             :             };                                                                  \
     405             : 
     406             :         BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
     407             :             BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _)
     408             : 
     409             :         #undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS
     410             :         #undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C
     411             :         ///////////////////////////////////////////////////////////////////////
     412             : 
     413             : #endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
     414             : 
     415             :     } // namespace impl
     416             : 
     417             : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
     418             : 
     419             : }} // namespace boost::spirit
     420             : 
     421             : #endif

Generated by: LCOV version 1.14