LCOV - code coverage report
Current view: top level - usr/include/boost/spirit/home/classic/utility - confix.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 10 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) 2002-2003 Hartmut Kaiser
       3             :     http://spirit.sourceforge.net/
       4             : 
       5             :   Distributed under the Boost Software License, Version 1.0. (See accompanying
       6             :   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7             : =============================================================================*/
       8             : #ifndef BOOST_SPIRIT_CONFIX_HPP
       9             : #define BOOST_SPIRIT_CONFIX_HPP
      10             : 
      11             : ///////////////////////////////////////////////////////////////////////////////
      12             : #include <boost/config.hpp>
      13             : #include <boost/spirit/home/classic/namespace.hpp>
      14             : #include <boost/spirit/home/classic/meta/as_parser.hpp>
      15             : #include <boost/spirit/home/classic/core/composite/operators.hpp>
      16             : 
      17             : #include <boost/spirit/home/classic/utility/confix_fwd.hpp>
      18             : #include <boost/spirit/home/classic/utility/impl/confix.ipp>
      19             : 
      20             : ///////////////////////////////////////////////////////////////////////////////
      21             : namespace boost { namespace spirit {
      22             : 
      23             : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
      24             : 
      25             : ///////////////////////////////////////////////////////////////////////////////
      26             : //
      27             : //  confix_parser class
      28             : //
      29             : //      Parses a sequence of 3 sub-matches. This class may
      30             : //      be used to parse structures, where the opening part is possibly
      31             : //      contained in the expression part and the whole sequence is only
      32             : //      parsed after seeing the closing part matching the first opening
      33             : //      subsequence. Example: C-comments:
      34             : //
      35             : //      /* This is a C-comment */
      36             : //
      37             : ///////////////////////////////////////////////////////////////////////////////
      38             : 
      39             : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
      40             : #pragma warning(push)
      41             : #pragma warning(disable:4512) //assignment operator could not be generated
      42             : #endif
      43             : 
      44             : template<typename NestedT = non_nested, typename LexemeT = non_lexeme>
      45             : struct confix_parser_gen;
      46             : 
      47             : template <
      48             :     typename OpenT, typename ExprT, typename CloseT, typename CategoryT,
      49             :     typename NestedT, typename LexemeT
      50             : >
      51             : struct confix_parser :
      52             :     public parser<
      53             :         confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
      54             :     >
      55             : {
      56             :     typedef
      57             :         confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
      58             :         self_t;
      59             : 
      60             :     confix_parser(OpenT const &open_, ExprT const &expr_, CloseT const &close_)
      61             :     : open(open_), expr(expr_), close(close_)
      62             :     {}
      63             : 
      64             :     template <typename ScannerT>
      65             :     typename parser_result<self_t, ScannerT>::type
      66             :     parse(ScannerT const& scan) const
      67             :     {
      68             :         return impl::confix_parser_type<CategoryT>::
      69             :             parse(NestedT(), LexemeT(), *this, scan, open, expr, close);
      70             :     }
      71             : 
      72             : private:
      73             : 
      74             :     typename as_parser<OpenT>::type::embed_t open;
      75             :     typename as_parser<ExprT>::type::embed_t expr;
      76             :     typename as_parser<CloseT>::type::embed_t close;
      77             : };
      78             : 
      79             : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
      80             : #pragma warning(pop)
      81             : #endif
      82             : 
      83             : ///////////////////////////////////////////////////////////////////////////////
      84             : //
      85             : //  Confix parser generator template
      86             : //
      87             : //      This is a helper for generating a correct confix_parser<> from
      88             : //      auxiliary parameters. There are the following types supported as
      89             : //      parameters yet: parsers, single characters and strings (see
      90             : //      as_parser).
      91             : //
      92             : //      If the body parser is an action_parser_category type parser (a parser
      93             : //      with an attached semantic action) we have to do something special. This
      94             : //      happens, if the user wrote something like:
      95             : //
      96             : //          confix_p(open, body[f], close)
      97             : //
      98             : //      where 'body' is the parser matching the body of the confix sequence
      99             : //      and 'f' is a functor to be called after matching the body. If we would
     100             : //      do nothing, the resulting code would parse the sequence as follows:
     101             : //
     102             : //          start >> (body[f] - close) >> close
     103             : //
     104             : //      what in most cases is not what the user expects.
     105             : //      (If this _is_ what you've expected, then please use the confix_p
     106             : //      generator function 'direct()', which will inhibit
     107             : //      re-attaching the actor to the body parser).
     108             : //
     109             : //      To make the confix parser behave as expected:
     110             : //
     111             : //          start >> (body - close)[f] >> close
     112             : //
     113             : //      the actor attached to the 'body' parser has to be re-attached to the
     114             : //      (body - close) parser construct, which will make the resulting confix
     115             : //      parser 'do the right thing'. This refactoring is done by the help of
     116             : //      the refactoring parsers (see the files refactoring.[hi]pp).
     117             : //
     118             : //      Additionally special care must be taken, if the body parser is a
     119             : //      unary_parser_category type parser as
     120             : //
     121             : //          confix_p(open, *anychar_p, close)
     122             : //
     123             : //      which without any refactoring would result in
     124             : //
     125             : //          start >> (*anychar_p - close) >> close
     126             : //
     127             : //      and will not give the expected result (*anychar_p will eat up all the
     128             : //      input up to the end of the input stream). So we have to refactor this
     129             : //      into:
     130             : //
     131             : //          start >> *(anychar_p - close) >> close
     132             : //
     133             : //      what will give the correct result.
     134             : //
     135             : //      The case, where the body parser is a combination of the two mentioned
     136             : //      problems (i.e. the body parser is a unary parser  with an attached
     137             : //      action), is handled accordingly too:
     138             : //
     139             : //          confix_p(start, (*anychar_p)[f], end)
     140             : //
     141             : //      will be parsed as expected:
     142             : //
     143             : //          start >> (*(anychar_p - end))[f] >> end.
     144             : //
     145             : ///////////////////////////////////////////////////////////////////////////////
     146             : 
     147             : template<typename NestedT, typename LexemeT>
     148             : struct confix_parser_gen
     149             : {
     150             :     // Generic generator function for creation of concrete confix parsers
     151             : 
     152             :     template<typename StartT, typename ExprT, typename EndT>
     153             :     struct paren_op_result_type
     154             :     {
     155             :         typedef confix_parser<
     156             :             typename as_parser<StartT>::type,
     157             :             typename as_parser<ExprT>::type,
     158             :             typename as_parser<EndT>::type,
     159             :             typename as_parser<ExprT>::type::parser_category_t,
     160             :             NestedT,
     161             :             LexemeT
     162             :         > type;
     163             :     };
     164             :   
     165             :     template<typename StartT, typename ExprT, typename EndT>
     166             :     typename paren_op_result_type<StartT, ExprT, EndT>::type 
     167             :     operator()(StartT const &start_, ExprT const &expr_, EndT const &end_) const
     168             :     {
     169             :         typedef typename paren_op_result_type<StartT,ExprT,EndT>::type 
     170             :             return_t;
     171             : 
     172             :         return return_t(
     173             :             as_parser<StartT>::convert(start_),
     174             :             as_parser<ExprT>::convert(expr_),
     175             :             as_parser<EndT>::convert(end_)
     176             :         );
     177             :     }
     178             : 
     179             :     // Generic generator function for creation of concrete confix parsers
     180             :     // which have an action directly attached to the ExprT part of the
     181             :     // parser (see comment above, no automatic refactoring)
     182             : 
     183             :     template<typename StartT, typename ExprT, typename EndT>
     184             :     struct direct_result_type
     185             :     {
     186             :         typedef confix_parser<
     187             :             typename as_parser<StartT>::type,
     188             :             typename as_parser<ExprT>::type,
     189             :             typename as_parser<EndT>::type,
     190             :             plain_parser_category,   // do not re-attach action
     191             :             NestedT,
     192             :             LexemeT
     193             :         > type;
     194             :     };
     195             : 
     196             :     template<typename StartT, typename ExprT, typename EndT>
     197             :     typename direct_result_type<StartT,ExprT,EndT>::type
     198             :     direct(StartT const &start_, ExprT const &expr_, EndT const &end_) const
     199             :     {
     200             :         typedef typename direct_result_type<StartT,ExprT,EndT>::type
     201             :             return_t;
     202             : 
     203             :         return return_t(
     204             :             as_parser<StartT>::convert(start_),
     205             :             as_parser<ExprT>::convert(expr_),
     206             :             as_parser<EndT>::convert(end_)
     207             :         );
     208             :     }
     209             : };
     210             : 
     211             : ///////////////////////////////////////////////////////////////////////////////
     212             : //
     213             : //  Predefined non_nested confix parser generators
     214             : //
     215             : ///////////////////////////////////////////////////////////////////////////////
     216             : 
     217             : const confix_parser_gen<non_nested, non_lexeme> confix_p =
     218             :     confix_parser_gen<non_nested, non_lexeme>();
     219             : 
     220             : ///////////////////////////////////////////////////////////////////////////////
     221             : //
     222             : //  Comments are special types of confix parsers
     223             : //
     224             : //      Comment parser generator template. This is a helper for generating a
     225             : //      correct confix_parser<> from auxiliary parameters, which is able to
     226             : //      parse comment constructs: (StartToken >> Comment text >> EndToken).
     227             : //
     228             : //      There are the following types supported as parameters yet: parsers,
     229             : //      single characters and strings (see as_parser).
     230             : //
     231             : //      There are two diffenerent predefined comment parser generators
     232             : //      (comment_p and comment_nest_p, see below), which may be used for
     233             : //      creating special comment parsers in two different ways.
     234             : //
     235             : //      If these are used with one parameter, a comment starting with the given
     236             : //      first parser parameter up to the end of the line is matched. So for
     237             : //      instance the following parser matches C++ style comments:
     238             : //
     239             : //          comment_p("//").
     240             : //
     241             : //      If these are used with two parameters, a comment starting with the
     242             : //      first parser parameter up to the second parser parameter is matched.
     243             : //      For instance a C style comment parser should be constrcuted as:
     244             : //
     245             : //          comment_p("/*", "*/").
     246             : //
     247             : //      Please note, that a comment is parsed implicitly as if the whole
     248             : //      comment_p(...) statement were embedded into a lexeme_d[] directive.
     249             : //
     250             : ///////////////////////////////////////////////////////////////////////////////
     251             : 
     252             : template<typename NestedT>
     253             : struct comment_parser_gen
     254             : {
     255             :     // Generic generator function for creation of concrete comment parsers
     256             :     // from an open token. The newline parser eol_p is used as the
     257             :     // closing token.
     258             : 
     259             :     template<typename StartT>
     260             :     struct paren_op1_result_type
     261             :     {
     262             :         typedef confix_parser<
     263             :             typename as_parser<StartT>::type,
     264             :             kleene_star<anychar_parser>,
     265             :             alternative<eol_parser, end_parser>,
     266             :             unary_parser_category,          // there is no action to re-attach
     267             :             NestedT,
     268             :             is_lexeme                       // insert implicit lexeme_d[]
     269             :         >
     270             :         type;
     271             :     };
     272             : 
     273             :     template<typename StartT>
     274             :     typename paren_op1_result_type<StartT>::type 
     275             :     operator() (StartT const &start_) const
     276             :     {
     277             :         typedef typename paren_op1_result_type<StartT>::type
     278             :             return_t;
     279             : 
     280             :         return return_t(
     281             :             as_parser<StartT>::convert(start_),
     282             :             *anychar_p,
     283             :             eol_p | end_p
     284             :         );
     285             :     }
     286             : 
     287             :     // Generic generator function for creation of concrete comment parsers
     288             :     // from an open and a close tokens.
     289             : 
     290             :     template<typename StartT, typename EndT>
     291             :     struct paren_op2_result_type
     292             :     {
     293             :         typedef confix_parser<
     294             :             typename as_parser<StartT>::type,
     295             :             kleene_star<anychar_parser>,
     296             :             typename as_parser<EndT>::type,
     297             :             unary_parser_category,          // there is no action to re-attach
     298             :             NestedT,
     299             :             is_lexeme                       // insert implicit lexeme_d[]
     300             :         > type;
     301             :     };
     302             : 
     303             :     template<typename StartT, typename EndT>
     304             :     typename paren_op2_result_type<StartT,EndT>::type
     305             :     operator() (StartT const &start_, EndT const &end_) const
     306             :     {
     307             :         typedef typename paren_op2_result_type<StartT,EndT>::type
     308             :             return_t;
     309             : 
     310             :         return return_t(
     311             :             as_parser<StartT>::convert(start_),
     312             :             *anychar_p,
     313             :             as_parser<EndT>::convert(end_)
     314             :         );
     315             :     }
     316             : };
     317             : 
     318             : ///////////////////////////////////////////////////////////////////////////////
     319             : //
     320             : //  Predefined non_nested comment parser generator
     321             : //
     322             : ///////////////////////////////////////////////////////////////////////////////
     323             : 
     324             : const comment_parser_gen<non_nested> comment_p =
     325             :     comment_parser_gen<non_nested>();
     326             : 
     327             : ///////////////////////////////////////////////////////////////////////////////
     328             : //
     329             : //  comment_nest_parser class
     330             : //
     331             : //      Parses a nested comments.
     332             : //      Example: nested PASCAL-comments:
     333             : //
     334             : //      { This is a { nested } PASCAL-comment }
     335             : //
     336             : ///////////////////////////////////////////////////////////////////////////////
     337             : 
     338             : template<typename OpenT, typename CloseT>
     339             : struct comment_nest_parser:
     340             :     public parser<comment_nest_parser<OpenT, CloseT> >
     341             : {
     342             :     typedef comment_nest_parser<OpenT, CloseT> self_t;
     343             : 
     344           0 :     comment_nest_parser(OpenT const &open_, CloseT const &close_):
     345             :         open(open_), close(close_)
     346             :     {}
     347             : 
     348             :     template<typename ScannerT>
     349             :     typename parser_result<self_t, ScannerT>::type
     350           0 :         parse(ScannerT const &scan) const
     351             :     {
     352             :         return do_parse(
     353           0 :             open >> *(*this | (anychar_p - close)) >> close,
     354           0 :             scan);
     355             :     }
     356             : 
     357             : private:
     358             :     template<typename ParserT, typename ScannerT>
     359             :     typename parser_result<self_t, ScannerT>::type
     360           0 :         do_parse(ParserT const &p, ScannerT const &scan) const
     361             :     {
     362             :         return
     363             :             impl::contiguous_parser_parse<
     364             :                 typename parser_result<ParserT, ScannerT>::type
     365           0 :             >(p, scan, scan);
     366             :     }
     367             : 
     368             :     typename as_parser<OpenT>::type::embed_t open;
     369             :     typename as_parser<CloseT>::type::embed_t close;
     370             : };
     371             : 
     372             : ///////////////////////////////////////////////////////////////////////////////
     373             : //
     374             : //  Predefined nested comment parser generator
     375             : //
     376             : ///////////////////////////////////////////////////////////////////////////////
     377             : 
     378             : template<typename OpenT, typename CloseT>
     379             : struct comment_nest_p_result
     380             : {
     381             :     typedef comment_nest_parser<
     382             :         typename as_parser<OpenT>::type,
     383             :         typename as_parser<CloseT>::type
     384             :     > type;
     385             : };
     386             : 
     387             : template<typename OpenT, typename CloseT>
     388             : inline typename comment_nest_p_result<OpenT,CloseT>::type 
     389           0 : comment_nest_p(OpenT const &open, CloseT const &close)
     390             : {
     391             :     typedef typename comment_nest_p_result<OpenT,CloseT>::type
     392             :         result_t;
     393             : 
     394             :     return result_t(
     395           0 :         as_parser<OpenT>::convert(open),
     396           0 :         as_parser<CloseT>::convert(close)
     397           0 :     );
     398             : }
     399             : 
     400             : ///////////////////////////////////////////////////////////////////////////////
     401             : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
     402             : 
     403             : }} // namespace BOOST_SPIRIT_CLASSIC_NS
     404             : 
     405             : #endif

Generated by: LCOV version 1.14