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

📄 utilities.hpp

📁 著名的Parser库Spirit在VC6上的Port
💻 HPP
📖 第 1 页 / 共 3 页
字号:
    // functions required for input iterators 
    BaseT const &operator* () const;
    list_action_iterator<ParserT, IteratorT, BaseT> &operator++ ();
    list_action_iterator<ParserT, IteratorT, BaseT> operator++ (int);
    bool operator== (
        list_action_iterator<ParserT, IteratorT, BaseT> const &rhs) const;
    bool operator!= (
        list_action_iterator<ParserT, IteratorT, BaseT> const &rhs) const;

    // functions required for parser integration
    IteratorT const &actposition() const;
    bool matched() const;
    void operator() (
        typename spirit::iterator_traits<IteratorT>::value_type const &match
        ) const;
    void operator() (
        IteratorT const &begin_match, IteratorT const &end_match) const;
    ParserT const &subject() const;

private:
    match read(bool firstread = false);

    ParserT const *parser;
    mutable BaseT value;
    IteratorT current;
    IteratorT const last;
    bool end_marker;
    bool saw_oneitem;
};

///////////////////////////////////////////////////////////////////////////////
// 
//  list_parser class
//
//      List parsers allow to parse constructs like 
//
//          item >> *(delim >> item)
//
//      where 'item' is an auxilliary expression to parse and 'delim' is an
//      auxilliary delimiter to parse. 
//
//      If ItemT 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:
//
//          list_p(item[f], delim)
//
//      where 'item' is the parser matching one item of the list sequence and 
//      'f' is a functor to be called after matching one item. If we would do 
//      nothing, the resulting code would parse the sequence as follows:
//
//          *(item[f] - delim) >> *(delim >> *(item[f] - delim))
//
//      what in most cases is not what the user expects. 
//      (If this _is_ what you've expected, then please use one of the list_p 
//      generator functions 'direct', which will inhibit re-attaching 
//      the actor to the item parser).
//
//      To make the list parser behave as expected:
//
//          (*(item - delim))[f] >> *(delim >> (*(item - delim))[f])
//
//      the actor attached to the 'item' parser has to be re-attached to the
//      *(item - delim) parser construct, which will make the resulting list
//      parser 'do the right thing'.
//
///////////////////////////////////////////////////////////////////////////////
template <
    typename ItemT, typename DelimT, 
    typename StringT = std::string,
    typename CategoryT = impl::dummy_category
>
struct list_parser :
    public parser<
           list_parser<
	       ItemT, DelimT, StringT, 
               typename impl::IF<boost::is_same<CategoryT, impl::dummy_category>::value,
               typename impl::determine_category<ItemT>::category ,
	       CategoryT 
              >::RET
            >
          >   
{
    typedef StringT string_t;
    typedef typename impl::IF<boost::is_same<CategoryT, impl::dummy_category>::value,
             typename impl::determine_category<ItemT>::category ,
	      CategoryT 
              >::RET category_type;
    typedef category_type parser_category;

    typedef list_parser<ItemT, DelimT, StringT, category_type > parser_with_correct_category; 

    list_parser(ItemT const &item_, const DelimT &delim_); 

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
   {
      return impl::list_parser_type<category_type>
            ::parse(first, last, item, delim);
   }

    template <typename ActionT>
    list_action<list_parser<ItemT, DelimT, StringT, category_type>, ActionT>
    operator[](ActionT const& actor) const
    {
        //  Borland internal compiler error if this
        //  is defined elsewhere (JDG)
        parser_with_correct_category* transformed_this = 
		 (parser_with_correct_category*)(this);
        return list_action<
		    list_parser<
		            ItemT, DelimT, StringT, category_type 
			     >, ActionT
			  >(*transformed_this,actor);
    }

    ItemT const &item_p() const { return item; }
    DelimT const &delim_p() const { return delim; }
    epsilon_ const &end_p() const { return epsilon; }

private:
    typename embed_trait<ItemT>::type item;
    typename embed_trait<DelimT>::type delim;
};

///////////////////////////////////////////////////////////////////////////////
// 
//  list_parser_ex class
//
//      Extended list parsers allow to parse constructs like 
//
//          item >> *(delim >> item) >> !end
//
//      where 'item' is an auxilliary expression to parse and 'delim' is an
//      auxilliary delimiter to parse. The 'end' token represents an optional
//      closing delimiter.
//
//      Same comments regarding re-attaching an eventually action code attached 
//      to the 'item' parser apply as in 'list_parser' (see above).
//
///////////////////////////////////////////////////////////////////////////////
template <
    typename ItemT, typename DelimT, typename EndT, 
    typename StringT = std::string,
    typename CategoryT = impl::dummy_category
>
struct list_parser_ex :
    public parser<
                 list_parser_ex<
		   ItemT, DelimT, EndT, StringT, 
                   typename impl::IF<boost::is_same<CategoryT, impl::dummy_category>::value,
                   typename impl::determine_category<ItemT>::category ,
	           CategoryT 
              >::RET
            >
          >   
{
    typedef StringT string_t;
    typedef typename impl::IF<boost::is_same<CategoryT, impl::dummy_category>::value,
             typename impl::determine_category<ItemT>::category ,
	      CategoryT 
              >::RET category_type;
    typedef category_type parser_category;

    list_parser_ex(
        ItemT const &item_, DelimT const &delim_, EndT const &end_);

     typedef list_parser_ex<ItemT , DelimT , EndT , category_type> parser_with_correct_category;

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
    {
      return impl::list_parser_type<category_type>
            ::parse(first, last, item, delim, end);
    }

    template <typename ActionT>
    list_action<list_parser_ex<ItemT, DelimT, EndT, StringT, category_type>, 
                ActionT>
    operator[](ActionT const& actor) const
    {
        //  Borland internal compiler error if this
        //  is defined elsewhere (JDG)
	parser_with_correct_category* transformed_this =
		 (parser_with_correct_category)(this) 
        return  list_action<list_parser_ex<ItemT, DelimT, EndT, StringT, category_type>, 
                ActionT> (*transformed_this, actor);
    }

    ItemT const &item_p() const { return item; }
    DelimT const &delim_p() const { return delim; }
    EndT const &end_p() const { return end; }

private:
    typename embed_trait<ItemT>::type item;
    typename embed_trait<DelimT>::type delim;
    typename embed_trait<EndT>::type end;
};

///////////////////////////////////////////////////////////////////////////////
//
// List parser generator template
//
//      This is a helper for generating a correct list_parser<> from
//      auxilliary parameters. There are the following types supported as
//      parameters yet: parsers, single characters and strings (see
//      impl::parser_type).
//
//      The list_parser_gen by itself can be used for parsing comma separated
//      lists without item formatting. 
//
///////////////////////////////////////////////////////////////////////////////
template <typename StringT = std::string>
struct list_parser_gen :
    public list_parser<anychar_, chlit<typename StringT::value_type>, StringT>
{
    typedef typename StringT::value_type CharT;

// construct the list_parser_gen object as an list parser for comma separated
// lists without item formatting.
    list_parser_gen() :
        list_parser<anychar_, chlit<CharT>, StringT>(anychar, chlit<CharT>(','))
    {
    }

// attach an action to the list_parser_gen by itself
    template <typename ActionT>
    list_action<list_parser<anychar_, chlit<CharT>, StringT>, ActionT>
    operator[](ActionT const& actor) const
    {
        //  Borland internal compiler error if this
        //  is defined elsewhere (JDG)
        typedef 
            list_action<list_parser<anychar_, chlit<CharT>, StringT>, ActionT> 
            return_t;

        return return_t(*this, actor);
    }

// The following generator functions should be used under normal circumstances.
// (the operator()(...) functions)

    // Generic generator functions for creation of concrete list parsers, which 
    // support 'normal' syntax: 
    //
    //      item >> *(delim >> item)
    //
    // If item isn't given, everything between two delimiters is matched.

    template<typename DelimT>
    list_parser<
        anychar_,
        typename impl::parser_type<DelimT>::parser_t,
        StringT,
        plain_parser_category          // anychar is a plain_parser type
    >
    operator()(DelimT const &delim_) const
    {
      typedef typename impl::parser_type<DelimT>::parser_t delim_t;
      typedef 
        list_parser<anychar_, delim_t, StringT, plain_parser_category> 
        return_t;

      return return_t(
        anychar,
        impl::parser_type<DelimT>::get(delim_));
    }


    template<typename ItemT, typename DelimT>
    list_parser<
        typename impl::parser_type<ItemT>::parser_t,
        typename impl::parser_type<DelimT>::parser_t,
        StringT
    >
    operator()(ItemT const &item_, DelimT const &delim_) const
    {
      typedef typename impl::parser_type<ItemT>::parser_t item_t;
      typedef typename impl::parser_type<DelimT>::parser_t delim_t;

      typedef list_parser<item_t, delim_t, StringT> return_t;

      return return_t(
        impl::parser_type_get<ItemT>::get(item_),
        impl::parser_type_get<DelimT>::get(delim_)
      );
    }



    // Generic generator function for creation of concrete list parsers, which 
    // support 'extended' syntax: 
    //
    //      item >> *(delim >> item) >> !end
    
    template<typename ItemT, typename DelimT, typename EndT>
    list_parser_ex<
        typename impl::parser_type<ItemT>::parser_t,
        typename impl::parser_type<DelimT>::parser_t,
        typename impl::parser_type<EndT>::parser_t,
        StringT
    >
    operator()(
        ItemT const &item_, DelimT const &delim_, EndT const &end_) const
    {
      typedef typename impl::parser_type<ItemT>::parser_t item_t;
      typedef typename impl::parser_type<DelimT>::parser_t delim_t;
      typedef typename impl::parser_type<EndT>::parser_t end_t;

      typedef list_parser_ex<item_t, delim_t, end_t, StringT> return_t;

      return return_t(
        impl::parser_type_get<ItemT>::get(item_),
        impl::parser_type_get<DelimT>::get(delim_),
        impl::parser_type_get<EndT>::get(end_) );
     }


// The following functions should be used, if the 'item' parser has an attached 
// semantic action and this action should _not_ be re-attached during parser 
// construction (see comment above).

    // Generic generator function for creation of concrete list parsers, which 
    // support 'normal' syntax: 
    //
    //      item >> *(delim >> item)

    template<typename ItemT, typename DelimT>
    list_parser<
        typename impl::parser_type<ItemT>::parser_t,
        typename impl::parser_type<DelimT>::parser_t,
        StringT,
        plain_parser_category        // inhibit action re-attachment
    >
    direct(ItemT const &item_,  DelimT const &delim_) const 
    {
      typedef typename impl::parser_type<ItemT>::parser_t item_t;
      typedef typename impl::parser_type<DelimT>::parser_t delim_t;

      typedef 
        list_parser<item_t, delim_t, StringT, plain_parser_category> 
        return_t;

      return return_t(
        impl::parser_type_get<ItemT>::get(item_),
        impl::parser_type_get<DelimT>::get(delim_));
   }


    // Generic generator function for creation of concrete list parsers, which 
    // support 'extended' syntax: 
    //
    //      item >> *(delim >> item) >> !end
    
    template<typename ItemT, typename DelimT, typename EndT>
    list_parser_ex<
        typename impl::parser_type<ItemT>::parser_t,
        typename impl::parser_type<DelimT>::parser_t,
        typename impl::parser_type<EndT>::parser_t,
        StringT,
        plain_parser_category        // inhibit action re-attachment
    >
    direct(
        ItemT const &item_, DelimT const &delim_, EndT const &end_) const
    {
       typedef typename impl::parser_type<ItemT>::parser_t item_t;
       typedef typename impl::parser_type<DelimT>::parser_t delim_t;
       typedef typename impl::parser_type<EndT>::parser_t end_t;

       typedef 
         list_parser_ex<item_t, delim_t, end_t, StringT, plain_parser_category> 
          return_t;

       return return_t(
        impl::parser_type_get<ItemT>::get(item_),
        impl::parser_type_get<DelimT>::get(delim_),
        impl::parser_type_get<EndT>::get(end_) );
    }
};

///////////////////////////////////////////////////////////////////////////////
//
//  Predefined list parser generator
//
//      The list_p parser generator can be used 
//        - by itself for parsing comma separated lists without item formatting 
//      or 
//        - for generating list parsers with auxilliary parser parameters 
//          for the 'item', 'delim' and 'end' subsequences.
//
///////////////////////////////////////////////////////////////////////////////
list_parser_gen<> list_p = list_parser_gen<>();

} // namespace spirit

#endif

⌨️ 快捷键说明

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