⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utilities.hpp

📁 著名的Parser库Spirit在VC6上的Port
💻 HPP
📖 第 1 页 / 共 3 页
字号:
    template<>
    struct parser_type<char>
    {
        typedef chlit<char> parser_t;
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type<wchar_t>
    {
        typedef chlit<wchar_t> parser_t;
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type<char const *>
    {
        typedef strlit<cstring<char> > parser_t;
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type<wchar_t const *>
    {
        typedef strlit<cstring<wchar_t> > parser_t;
    };

    //////////////////////////////////////////////////////// 

    template <class T>
    struct parser_type_get
    {
       static T* t(void);  	     

        typedef  impl::IF<boost::is_array<T>::value,
              selector1,
	      selector2>::RET selector_t;  

       typedef typename parser_type_helper<(sizeof(selector_t))>
        ::template inner<T>::parser_t parser_t;

       typedef typename parser_type_helper<(sizeof(selector_t))>
        ::template inner<T>::return_t return_t;

       typedef typename parser_type_helper<(sizeof(selector_t))>
        ::template inner<T>::dispatcher_t dispatcher_t;

       typedef typename parser_type_helper<(sizeof(selector_t))>
        ::template inner<T>::parameter_t parameter_t;


       static return_t get_helper(parameter_t x , selector1) { return parser_t(x); }
       static return_t get_helper(parameter_t x , selector2) { return x; }
        
       static  return_t get( parameter_t x ) {return  get_helper(x, dispatcher_t()); }   
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type_get<char>
    {
        typedef chlit<char> parser_t;
        static parser_t get(char ch) { return parser_t(ch); }
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type_get<wchar_t>
    {
        typedef chlit<wchar_t> parser_t;
        static parser_t get(wchar_t ch) { return parser_t(ch); }
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type_get<char const *>
    {
        typedef strlit<cstring<char> > parser_t;
        static parser_t get(char const* str) { return parser_t(str); }
    };

    //////////////////////////////////////////////////////// 
    template<>
    struct parser_type_get<wchar_t const *>
    {
        typedef strlit<cstring<wchar_t> > parser_t;
        static parser_t get(wchar_t const* str) { return parser_t(str); }
    };

        
    //////////////////////////////////////////////////////// 
    struct dummy_category {}; 

    template<typename T>
    struct determine_category 
    {
        typedef typename parser_type<T>::parser_t type_of_parser;
	typedef type_of_parser::parser_category category; 
    };

    //////////////////////////////////////////////////////// 
   template <typename NestedT, typename CategoryT>
   struct confix_parser_type;

} // namespace impl

///////////////////////////////////////////////////////////////////////////////
//
//  confix_parser class
//
//      Parses a (possibly nested) sequence of 3 sub-matches. This class may
//      be used to parse structures, where the opening part is possibly
//      contained in the expression part and the whole sequence is only
//      parsed after seeing the closing part matching the first opening
//      subsequence. Example: nested PASCAL-comments:
//
//      { This is a { nested } PASCAL-comment }
//
///////////////////////////////////////////////////////////////////////////////
template <
    typename OpenT, typename ExprT, typename CloseT,
    typename NestedT = non_nested, 
    typename CategoryT = impl::dummy_category
>
struct confix_parser :
    public parser<
      confix_parser<
      OpenT, ExprT, CloseT, NestedT, 
      typename impl::IF<boost::is_same<CategoryT, impl::dummy_category>::value,
              typename impl::determine_category<ExprT>::category ,
	      CategoryT 
              >::RET
      >
    >   
{
    confix_parser(OpenT const &open_, ExprT const &expr_, CloseT const &close_) ; 

    typedef typename impl::IF<boost::is_same<CategoryT, impl::dummy_category>::value,
             typename impl::determine_category<ExprT>::category ,
	      CategoryT 
              >::RET category_type;

    typedef confix_parser<OpenT, ExprT, CloseT, NestedT, category_type> 
	    parser_with_correct_category; 

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
    {
      parser_with_correct_category* transformed_this =
	       (parser_with_correct_category*)(this); 
      return impl::confix_parser_type<NestedT, category_type>::
       parse(first, last, *transformed_this, open, expr, close);
    }


private:
    typename embed_trait<OpenT>::type open;
    typename embed_trait<ExprT>::type expr;
    typename embed_trait<CloseT>::type close;
};

///////////////////////////////////////////////////////////////////////////////
//
// Confix parser generator template
//
//      This is a helper for generating a correct confix_parser<> from
//      auxilliary parameters. There are the following types supported as
//      parameters yet: parsers, single characters and strings (see
//      impl::parser_type).
//
//      If ExprT is an action_parser_category type (parser with an attached 
//      semantic action) we have to do something special. This happens, if the 
//      user wrote something like:
//
//          confix_p(open, body[f], close)
//
//      where 'body' is the parser matching the body of the confix sequence 
//      and 'f' is a functor to be called after matching the body. If we would 
//      do nothing, the resulting code would parse the sequence as follows:
//
//          start >> *(body[f] - close) >> close
//
//      what in most cases is not what the user expects. 
//      (If this _is_ what you've expected, then please use the confix_p or
//      confix_nest_p generator function 'direct', which will inhibit 
//      re-attaching the actor to the body parser).
//
//      To make the confix parser behave as expected:
//
//          start >> (*(body - close))[f] >> close
//
//      the actor attached to the 'body' parser has to be re-attached to the
//      *(body - close) parser construct, which will make the resulting confix
//      parser 'do the right thing'.
//
///////////////////////////////////////////////////////////////////////////////
template<class NestedT>
struct confix_parser_gen
{
    // Generic generator function for creation of concrete confix parsers
    template<typename StartT, typename ExprT, typename EndT>
    confix_parser<
        typename impl::parser_type<StartT>::parser_t,
        typename impl::parser_type<ExprT>::parser_t , 
        typename impl::parser_type<EndT>::parser_t,
        NestedT,
        typename impl::determine_category<ExprT>::category
    > 
        operator()(
        StartT const &start_, ExprT const &expr_, EndT const &end_) const
    {
      typedef typename impl::parser_type<StartT>::parser_t start_t;
      typedef typename impl::parser_type<ExprT>::parser_t expr_t ;
      typedef typename impl::parser_type<EndT>::parser_t end_t;
      typedef
        typename impl::determine_category<ExprT>::category
        parser_category;

        typedef confix_parser<start_t, expr_t, end_t, NestedT, parser_category> return_t;
        return return_t(
                impl::parser_type_get<StartT>::get(start_),
                impl::parser_type_get<ExprT>::get(expr_),
                impl::parser_type_get<EndT>::get(end_)
           ); 
	   
     }

    	     

    // Generic generator function for creation of concrete confix parsers
    // which have a action directly attached to the ExprT part of the
    // parser (see comment above)

    template<typename StartT, typename ExprT, typename EndT>
    confix_parser<
        typename impl::parser_type<StartT>::parser_t,
        typename impl::parser_type<ExprT>::parser_t,
        typename impl::parser_type<EndT>::parser_t,
        NestedT,
        plain_parser_category // do not re-attach action
    >
    direct(
        StartT const &start_, ExprT const &expr_, EndT const &end_) const
   {
    typedef typename impl::parser_type<StartT>::parser_t start_t;
    typedef typename impl::parser_type<ExprT>::parser_t expr_t;
    typedef typename impl::parser_type<EndT>::parser_t end_t;
    typedef plain_parser_category parser_category;

    typedef
        confix_parser<start_t, expr_t, end_t, NestedT, parser_category>
        return_t;

    return return_t(
                impl::parser_type_get<StartT>::get(start_),
                impl::parser_type_get<ExprT>::get(expr_),
                impl::parser_type_get<EndT>::get(end_)
           );
   }

};

///////////////////////////////////////////////////////////////////////////////
//
//  Predefined non_nested and nested confix parser generators
//
///////////////////////////////////////////////////////////////////////////////
const confix_parser_gen<non_nested> confix_p = confix_parser_gen<non_nested>();
const confix_parser_gen<nested> confix_nest_p = confix_parser_gen<nested>();

///////////////////////////////////////////////////////////////////////////////
//
//  Comments are special types of confix parsers
//
//      Comment parser generator template. This is a helper for generating a
//      correct confix_parser<> from auxilliary parameters, which is able to
//      parse comment constructs: (StartToken >> Comment text >> EndToken).
//      There are the following types supported as parameters yet: parsers,
//      single characters and strings (see impl::parser_type).
//
///////////////////////////////////////////////////////////////////////////////
template<typename NestedT>
struct comment_parser_gen
{
    // generic generator function for creation of concrete comment parsers

    template<typename StartT, typename EndT>
    confix_parser<
        typename impl::parser_type<StartT>::parser_t,
        anychar_,
        typename impl::parser_type<EndT>::parser_t,
        NestedT
    >
    operator() (StartT const &start_, EndT const &end_) const
    {
      typedef typename impl::parser_type<StartT>::parser_t start_t;
      typedef typename impl::parser_type<EndT>::parser_t end_t;

      typedef confix_parser<start_t, anychar_, end_t, NestedT> return_t;

      return return_t(
        impl::parser_type_get<StartT>::get(start_),
        anychar,
        impl::parser_type_get<EndT>::get(end_) );
   }

     
};

///////////////////////////////////////////////////////////////////////////////
//
//  Predefined non_nested and nested comment parser generator
//
///////////////////////////////////////////////////////////////////////////////
comment_parser_gen<non_nested> comment_p = comment_parser_gen<non_nested>();
comment_parser_gen<nested> comment_nest_p = comment_parser_gen<nested>();

///////////////////////////////////////////////////////////////////////////////
// 
//  list_action class
//
//      Links an list parser with a user defined semantic action.
//      The semantic action may be a function or a functor. A function
//      should be compatible with the interface:
//
//          template <typename IteratorT>
//          void f (IteratorT it);
//
//      Where 'it' is an input iterator for iteration over the matched items
//      in the list. Dereferencing this iterator will yield in getting a
//      list item as a StringT. 
//
//      A functor should have a member operator() with a compatible signature
//      as above. The matching item is passed into the function/functor.
//      This is the default class that list parsers use when dealing with
//      the construct:
//
//          p[f]
//
//      where p is a parser and f is a function or functor.
//
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename ActionT>
struct list_action :
    public unary<ParserT>,
    public parser<list_action<ParserT, ActionT> > 
{
    typedef action_parser_category parser_category;

    list_action(ParserT const& subject, ActionT const& actor_);

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
   {
      typedef impl::strip_scanner<IteratorT> strip_scanner;
      typedef list_action_iterator<ParserT, IteratorT, 
         ParserT::string_t> iterator_t;

      typename strip_scanner::iterator_type begin = strip_scanner::get(first);
      iterator_t list_it (&subject(), first, last);

      actor(list_it, iterator_t());
      if (list_it.matched()) {
         first = list_it.actposition();
        return match (std::distance(begin, strip_scanner::get(first)));
      }
      return match();
   }



    ActionT const &predicate() const { return actor; }

private:

    typename embed_trait<ActionT>::type actor;
};

///////////////////////////////////////////////////////////////////////////////
// 
//  class list_action_iterator
//
//      The list_action_iterator is an input iterator, which allows access
//      to the successfully parsed list items.
//
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename IteratorT, typename BaseT = std::string>
struct list_action_iterator 
{
    typedef std::input_iterator_tag iterator_category;
    typedef BaseT                   value_type;
    typedef ptrdiff_t               difference_type;
    typedef BaseT *                 pointer;
    typedef BaseT &                 reference;

    list_action_iterator();
    list_action_iterator(
        ParserT const *parser, IteratorT &first, IteratorT const &last);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -