📄 utilities.hpp
字号:
// 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 + -