os/ossrv/ossrv_pub/boost_apis/boost/spirit/utility/confix.hpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/spirit/utility/confix.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,392 @@
     1.4 +/*=============================================================================
     1.5 +    Copyright (c) 2002-2003 Hartmut Kaiser
     1.6 +    http://spirit.sourceforge.net/
     1.7 +
     1.8 +    Use, modification and distribution is subject to the Boost Software
     1.9 +    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    1.10 +    http://www.boost.org/LICENSE_1_0.txt)
    1.11 +=============================================================================*/
    1.12 +#ifndef BOOST_SPIRIT_CONFIX_HPP
    1.13 +#define BOOST_SPIRIT_CONFIX_HPP
    1.14 +
    1.15 +///////////////////////////////////////////////////////////////////////////////
    1.16 +#include <boost/config.hpp>
    1.17 +#include <boost/spirit/meta/as_parser.hpp>
    1.18 +#include <boost/spirit/core/composite/operators.hpp>
    1.19 +
    1.20 +#include <boost/spirit/utility/confix_fwd.hpp>
    1.21 +#include <boost/spirit/utility/impl/confix.ipp>
    1.22 +
    1.23 +///////////////////////////////////////////////////////////////////////////////
    1.24 +namespace boost { namespace spirit {
    1.25 +
    1.26 +///////////////////////////////////////////////////////////////////////////////
    1.27 +//
    1.28 +//  confix_parser class
    1.29 +//
    1.30 +//      Parses a sequence of 3 sub-matches. This class may
    1.31 +//      be used to parse structures, where the opening part is possibly
    1.32 +//      contained in the expression part and the whole sequence is only
    1.33 +//      parsed after seeing the closing part matching the first opening
    1.34 +//      subsequence. Example: C-comments:
    1.35 +//
    1.36 +//      /* This is a C-comment */
    1.37 +//
    1.38 +///////////////////////////////////////////////////////////////////////////////
    1.39 +
    1.40 +template<typename NestedT = non_nested, typename LexemeT = non_lexeme>
    1.41 +struct confix_parser_gen;
    1.42 +
    1.43 +template <
    1.44 +    typename OpenT, typename ExprT, typename CloseT, typename CategoryT,
    1.45 +    typename NestedT, typename LexemeT
    1.46 +>
    1.47 +struct confix_parser :
    1.48 +    public parser<
    1.49 +        confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
    1.50 +    >
    1.51 +{
    1.52 +    typedef
    1.53 +        confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
    1.54 +        self_t;
    1.55 +
    1.56 +    confix_parser(OpenT const &open_, ExprT const &expr_, CloseT const &close_)
    1.57 +    : open(open_), expr(expr_), close(close_)
    1.58 +    {}
    1.59 +
    1.60 +    template <typename ScannerT>
    1.61 +    typename parser_result<self_t, ScannerT>::type
    1.62 +    parse(ScannerT const& scan) const
    1.63 +    {
    1.64 +        return impl::confix_parser_type<CategoryT>::
    1.65 +            parse(NestedT(), LexemeT(), *this, scan, open, expr, close);
    1.66 +    }
    1.67 +
    1.68 +private:
    1.69 +
    1.70 +    typename as_parser<OpenT>::type::embed_t open;
    1.71 +    typename as_parser<ExprT>::type::embed_t expr;
    1.72 +    typename as_parser<CloseT>::type::embed_t close;
    1.73 +};
    1.74 +
    1.75 +///////////////////////////////////////////////////////////////////////////////
    1.76 +//
    1.77 +//  Confix parser generator template
    1.78 +//
    1.79 +//      This is a helper for generating a correct confix_parser<> from
    1.80 +//      auxiliary parameters. There are the following types supported as
    1.81 +//      parameters yet: parsers, single characters and strings (see
    1.82 +//      as_parser).
    1.83 +//
    1.84 +//      If the body parser is an action_parser_category type parser (a parser
    1.85 +//      with an attached semantic action) we have to do something special. This
    1.86 +//      happens, if the user wrote something like:
    1.87 +//
    1.88 +//          confix_p(open, body[f], close)
    1.89 +//
    1.90 +//      where 'body' is the parser matching the body of the confix sequence
    1.91 +//      and 'f' is a functor to be called after matching the body. If we would
    1.92 +//      do nothing, the resulting code would parse the sequence as follows:
    1.93 +//
    1.94 +//          start >> (body[f] - close) >> close
    1.95 +//
    1.96 +//      what in most cases is not what the user expects.
    1.97 +//      (If this _is_ what you've expected, then please use the confix_p
    1.98 +//      generator function 'direct()', which will inhibit
    1.99 +//      re-attaching the actor to the body parser).
   1.100 +//
   1.101 +//      To make the confix parser behave as expected:
   1.102 +//
   1.103 +//          start >> (body - close)[f] >> close
   1.104 +//
   1.105 +//      the actor attached to the 'body' parser has to be re-attached to the
   1.106 +//      (body - close) parser construct, which will make the resulting confix
   1.107 +//      parser 'do the right thing'. This refactoring is done by the help of
   1.108 +//      the refactoring parsers (see the files refactoring.[hi]pp).
   1.109 +//
   1.110 +//      Additionally special care must be taken, if the body parser is a
   1.111 +//      unary_parser_category type parser as
   1.112 +//
   1.113 +//          confix_p(open, *anychar_p, close)
   1.114 +//
   1.115 +//      which without any refactoring would result in
   1.116 +//
   1.117 +//          start >> (*anychar_p - close) >> close
   1.118 +//
   1.119 +//      and will not give the expected result (*anychar_p will eat up all the
   1.120 +//      input up to the end of the input stream). So we have to refactor this
   1.121 +//      into:
   1.122 +//
   1.123 +//          start >> *(anychar_p - close) >> close
   1.124 +//
   1.125 +//      what will give the correct result.
   1.126 +//
   1.127 +//      The case, where the body parser is a combination of the two mentioned
   1.128 +//      problems (i.e. the body parser is a unary parser  with an attached
   1.129 +//      action), is handled accordingly too:
   1.130 +//
   1.131 +//          confix_p(start, (*anychar_p)[f], end)
   1.132 +//
   1.133 +//      will be parsed as expected:
   1.134 +//
   1.135 +//          start >> (*(anychar_p - end))[f] >> end.
   1.136 +//
   1.137 +///////////////////////////////////////////////////////////////////////////////
   1.138 +
   1.139 +template<typename NestedT, typename LexemeT>
   1.140 +struct confix_parser_gen
   1.141 +{
   1.142 +    // Generic generator function for creation of concrete confix parsers
   1.143 +
   1.144 +    template<typename StartT, typename ExprT, typename EndT>
   1.145 +    struct paren_op_result_type
   1.146 +    {
   1.147 +        typedef confix_parser<
   1.148 +            typename as_parser<StartT>::type,
   1.149 +            typename as_parser<ExprT>::type,
   1.150 +            typename as_parser<EndT>::type,
   1.151 +            typename as_parser<ExprT>::type::parser_category_t,
   1.152 +            NestedT,
   1.153 +            LexemeT
   1.154 +        > type;
   1.155 +    };
   1.156 +  
   1.157 +    template<typename StartT, typename ExprT, typename EndT>
   1.158 +    typename paren_op_result_type<StartT, ExprT, EndT>::type 
   1.159 +    operator()(StartT const &start_, ExprT const &expr_, EndT const &end_) const
   1.160 +    {
   1.161 +        typedef typename paren_op_result_type<StartT,ExprT,EndT>::type 
   1.162 +            return_t;
   1.163 +
   1.164 +        return return_t(
   1.165 +            as_parser<StartT>::convert(start_),
   1.166 +            as_parser<ExprT>::convert(expr_),
   1.167 +            as_parser<EndT>::convert(end_)
   1.168 +        );
   1.169 +    }
   1.170 +
   1.171 +    // Generic generator function for creation of concrete confix parsers
   1.172 +    // which have an action directly attached to the ExprT part of the
   1.173 +    // parser (see comment above, no automatic refactoring)
   1.174 +
   1.175 +    template<typename StartT, typename ExprT, typename EndT>
   1.176 +    struct direct_result_type
   1.177 +    {
   1.178 +        typedef confix_parser<
   1.179 +            typename as_parser<StartT>::type,
   1.180 +            typename as_parser<ExprT>::type,
   1.181 +            typename as_parser<EndT>::type,
   1.182 +            plain_parser_category,   // do not re-attach action
   1.183 +            NestedT,
   1.184 +            LexemeT
   1.185 +        > type;
   1.186 +    };
   1.187 +
   1.188 +    template<typename StartT, typename ExprT, typename EndT>
   1.189 +    typename direct_result_type<StartT,ExprT,EndT>::type
   1.190 +    direct(StartT const &start_, ExprT const &expr_, EndT const &end_) const
   1.191 +    {
   1.192 +        typedef typename direct_result_type<StartT,ExprT,EndT>::type
   1.193 +            return_t;
   1.194 +
   1.195 +        return return_t(
   1.196 +            as_parser<StartT>::convert(start_),
   1.197 +            as_parser<ExprT>::convert(expr_),
   1.198 +            as_parser<EndT>::convert(end_)
   1.199 +        );
   1.200 +    }
   1.201 +};
   1.202 +
   1.203 +///////////////////////////////////////////////////////////////////////////////
   1.204 +//
   1.205 +//  Predefined non_nested confix parser generators
   1.206 +//
   1.207 +///////////////////////////////////////////////////////////////////////////////
   1.208 +
   1.209 +const confix_parser_gen<non_nested, non_lexeme> confix_p =
   1.210 +    confix_parser_gen<non_nested, non_lexeme>();
   1.211 +
   1.212 +///////////////////////////////////////////////////////////////////////////////
   1.213 +//
   1.214 +//  Comments are special types of confix parsers
   1.215 +//
   1.216 +//      Comment parser generator template. This is a helper for generating a
   1.217 +//      correct confix_parser<> from auxiliary parameters, which is able to
   1.218 +//      parse comment constructs: (StartToken >> Comment text >> EndToken).
   1.219 +//
   1.220 +//      There are the following types supported as parameters yet: parsers,
   1.221 +//      single characters and strings (see as_parser).
   1.222 +//
   1.223 +//      There are two diffenerent predefined comment parser generators
   1.224 +//      (comment_p and comment_nest_p, see below), which may be used for
   1.225 +//      creating special comment parsers in two different ways.
   1.226 +//
   1.227 +//      If these are used with one parameter, a comment starting with the given
   1.228 +//      first parser parameter up to the end of the line is matched. So for
   1.229 +//      instance the following parser matches C++ style comments:
   1.230 +//
   1.231 +//          comment_p("//").
   1.232 +//
   1.233 +//      If these are used with two parameters, a comment starting with the
   1.234 +//      first parser parameter up to the second parser parameter is matched.
   1.235 +//      For instance a C style comment parser should be constrcuted as:
   1.236 +//
   1.237 +//          comment_p("/*", "*/").
   1.238 +//
   1.239 +//      Please note, that a comment is parsed implicitly as if the whole
   1.240 +//      comment_p(...) statement were embedded into a lexeme_d[] directive.
   1.241 +//
   1.242 +///////////////////////////////////////////////////////////////////////////////
   1.243 +
   1.244 +template<typename NestedT>
   1.245 +struct comment_parser_gen
   1.246 +{
   1.247 +    // Generic generator function for creation of concrete comment parsers
   1.248 +    // from an open token. The newline parser eol_p is used as the
   1.249 +    // closing token.
   1.250 +
   1.251 +    template<typename StartT>
   1.252 +    struct paren_op1_result_type
   1.253 +    {
   1.254 +        typedef confix_parser<
   1.255 +            typename as_parser<StartT>::type,
   1.256 +            kleene_star<anychar_parser>,
   1.257 +            alternative<eol_parser, end_parser>,
   1.258 +            unary_parser_category,          // there is no action to re-attach
   1.259 +            NestedT,
   1.260 +            is_lexeme                       // insert implicit lexeme_d[]
   1.261 +        >
   1.262 +        type;
   1.263 +    };
   1.264 +
   1.265 +    template<typename StartT>
   1.266 +    typename paren_op1_result_type<StartT>::type 
   1.267 +    operator() (StartT const &start_) const
   1.268 +    {
   1.269 +        typedef typename paren_op1_result_type<StartT>::type
   1.270 +            return_t;
   1.271 +
   1.272 +        return return_t(
   1.273 +            as_parser<StartT>::convert(start_),
   1.274 +            *anychar_p,
   1.275 +            eol_p | end_p
   1.276 +        );
   1.277 +    }
   1.278 +
   1.279 +    // Generic generator function for creation of concrete comment parsers
   1.280 +    // from an open and a close tokens.
   1.281 +
   1.282 +    template<typename StartT, typename EndT>
   1.283 +    struct paren_op2_result_type
   1.284 +    {
   1.285 +        typedef confix_parser<
   1.286 +            typename as_parser<StartT>::type,
   1.287 +            kleene_star<anychar_parser>,
   1.288 +            typename as_parser<EndT>::type,
   1.289 +            unary_parser_category,          // there is no action to re-attach
   1.290 +            NestedT,
   1.291 +            is_lexeme                       // insert implicit lexeme_d[]
   1.292 +        > type;
   1.293 +    };
   1.294 +
   1.295 +    template<typename StartT, typename EndT>
   1.296 +    typename paren_op2_result_type<StartT,EndT>::type
   1.297 +    operator() (StartT const &start_, EndT const &end_) const
   1.298 +    {
   1.299 +        typedef typename paren_op2_result_type<StartT,EndT>::type
   1.300 +            return_t;
   1.301 +
   1.302 +        return return_t(
   1.303 +            as_parser<StartT>::convert(start_),
   1.304 +            *anychar_p,
   1.305 +            as_parser<EndT>::convert(end_)
   1.306 +        );
   1.307 +    }
   1.308 +};
   1.309 +
   1.310 +///////////////////////////////////////////////////////////////////////////////
   1.311 +//
   1.312 +//  Predefined non_nested comment parser generator
   1.313 +//
   1.314 +///////////////////////////////////////////////////////////////////////////////
   1.315 +
   1.316 +const comment_parser_gen<non_nested> comment_p =
   1.317 +    comment_parser_gen<non_nested>();
   1.318 +
   1.319 +///////////////////////////////////////////////////////////////////////////////
   1.320 +//
   1.321 +//  comment_nest_parser class
   1.322 +//
   1.323 +//      Parses a nested comments.
   1.324 +//      Example: nested PASCAL-comments:
   1.325 +//
   1.326 +//      { This is a { nested } PASCAL-comment }
   1.327 +//
   1.328 +///////////////////////////////////////////////////////////////////////////////
   1.329 +
   1.330 +template<typename OpenT, typename CloseT>
   1.331 +struct comment_nest_parser:
   1.332 +    public parser<comment_nest_parser<OpenT, CloseT> >
   1.333 +{
   1.334 +    typedef comment_nest_parser<OpenT, CloseT> self_t;
   1.335 +
   1.336 +    comment_nest_parser(OpenT const &open_, CloseT const &close_):
   1.337 +        open(open_), close(close_)
   1.338 +    {}
   1.339 +
   1.340 +    template<typename ScannerT>
   1.341 +    typename parser_result<self_t, ScannerT>::type
   1.342 +        parse(ScannerT const &scan) const
   1.343 +    {
   1.344 +        return do_parse(
   1.345 +            open >> *(*this | (anychar_p - close)) >> close,
   1.346 +            scan);
   1.347 +    }
   1.348 +
   1.349 +private:
   1.350 +    template<typename ParserT, typename ScannerT>
   1.351 +    typename parser_result<self_t, ScannerT>::type
   1.352 +        do_parse(ParserT const &p, ScannerT const &scan) const
   1.353 +    {
   1.354 +        return
   1.355 +            impl::contiguous_parser_parse<
   1.356 +                typename parser_result<ParserT, ScannerT>::type
   1.357 +            >(p, scan, scan);
   1.358 +    }
   1.359 +
   1.360 +    typename as_parser<OpenT>::type::embed_t open;
   1.361 +    typename as_parser<CloseT>::type::embed_t close;
   1.362 +};
   1.363 +
   1.364 +///////////////////////////////////////////////////////////////////////////////
   1.365 +//
   1.366 +//  Predefined nested comment parser generator
   1.367 +//
   1.368 +///////////////////////////////////////////////////////////////////////////////
   1.369 +
   1.370 +template<typename OpenT, typename CloseT>
   1.371 +struct comment_nest_p_result
   1.372 +{
   1.373 +    typedef comment_nest_parser<
   1.374 +        typename as_parser<OpenT>::type,
   1.375 +        typename as_parser<CloseT>::type
   1.376 +    > type;
   1.377 +};
   1.378 +
   1.379 +template<typename OpenT, typename CloseT>
   1.380 +inline typename comment_nest_p_result<OpenT,CloseT>::type 
   1.381 +comment_nest_p(OpenT const &open, CloseT const &close)
   1.382 +{
   1.383 +    typedef typename comment_nest_p_result<OpenT,CloseT>::type
   1.384 +        result_t;
   1.385 +
   1.386 +    return result_t(
   1.387 +        as_parser<OpenT>::convert(open),
   1.388 +        as_parser<CloseT>::convert(close)
   1.389 +    );
   1.390 +}
   1.391 +
   1.392 +///////////////////////////////////////////////////////////////////////////////
   1.393 +}} // namespace boost::spirit
   1.394 +
   1.395 +#endif