Boost-Graph
view release on metacpan or search on metacpan
include/boost/spirit/utility/loops.hpp view on Meta::CPAN
// This class is parametizable and can accept constant arguments
// (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
// repeat_p (ref (n)) [p]).
//
///////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename ExactT>
class fixed_loop
: public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
{
public:
typedef fixed_loop<ParserT, ExactT> self_t;
typedef unary<ParserT, parser<self_t> > base_t;
fixed_loop (ParserT const & subject, ExactT const & exact)
: base_t(subject), m_exact(exact) {}
template <typename ScannerT>
typename parser_result <self_t, ScannerT>::type
parse (ScannerT const & scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
result_t hit = scan.empty_match();
std::size_t n = m_exact;
for (std::size_t i = 0; i < n; ++i)
{
if (result_t next = this->subject().parse(scan))
{
scan.concat_match(hit, next);
}
else
{
return scan.no_match();
}
}
return hit;
}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
private:
ExactT m_exact;
};
///////////////////////////////////////////////////////////////////////////////
//
// finite_loop class
//
// This class takes care of the construct:
//
// repeat_p (min, max) [p]
//
// where 'p' is a parser, 'min' and 'max' specifies the minimum and
// maximum iterations over 'p'. The parser iterates over the input
// at least 'min' times and at most 'max' times. The parse function
// fails if the parser does not match the input at least 'min' times
// and at most 'max' times.
//
// This class is parametizable and can accept constant arguments
// (e.g. repeat_p (5, 10) [p]) as well as references to variables
// (e.g. repeat_p (ref (n1), ref (n2)) [p]).
//
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename MinT, typename MaxT>
class finite_loop
: public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
{
public:
typedef finite_loop <ParserT, MinT, MaxT> self_t;
typedef unary<ParserT, parser<self_t> > base_t;
finite_loop (ParserT const & subject, MinT const & min, MaxT const & max)
: base_t(subject), m_min(min), m_max(max) {}
template <typename ScannerT>
typename parser_result <self_t, ScannerT>::type
parse(ScannerT const & scan) const
{
BOOST_SPIRIT_ASSERT(m_min <= m_max);
typedef typename parser_result<self_t, ScannerT>::type result_t;
result_t hit = scan.empty_match();
std::size_t n1 = m_min;
std::size_t n2 = m_max;
for (std::size_t i = 0; i < n2; ++i)
{
typename ScannerT::iterator_t save = scan.first;
result_t next = this->subject().parse(scan);
if (!next)
{
if (i >= n1)
{
scan.first = save;
break;
}
else
{
return scan.no_match();
}
}
scan.concat_match(hit, next);
}
return hit;
}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
( run in 1.027 second using v1.01-cache-2.11-cpan-71847e10f99 )