📄 regexpr2.cpp
字号:
template< typename U > struct rebind { typedef eol_t<U> other; };
};
// Evaluates perl's end-of-string conditions, either the end of the string, or a
// newline character followed by end of string. ( Only used by $ and /Z assertions )
template< typename CSTRINGS >
struct peos_t
{
template< typename CI >
static bool eval( match_param<CI> const & param, CI iter )
{
typedef typename std::iterator_traits<CI>::value_type CH;
typedef std::char_traits<CH> traits_type;
return param.istop == iter
|| ( traits_type::eq( REGEX_CHAR(CH,'\n'), *iter ) && param.istop == ++iter );
}
template< typename U > struct rebind { typedef peos_t<U> other; };
};
template<>
struct peos_t<true_t>
{
template< typename CI >
static bool eval( match_param<CI> const &, CI iter )
{
typedef typename std::iterator_traits<CI>::value_type CH;
typedef std::char_traits<CH> traits_type;
return traits_type::eq( REGEX_CHAR(CH,'\0'), *iter )
|| ( traits_type::eq( REGEX_CHAR(CH,'\n'), *iter )
&& traits_type::eq( REGEX_CHAR(CH,'\0'), *++iter ) );
}
template< typename U > struct rebind { typedef peos_t<U> other; };
};
// compare two characters, case-sensitive
template< typename CH >
struct ch_neq_t
{
typedef CH char_type;
typedef std::char_traits<char_type> traits_type;
static bool eval( register CH ch1, register CH ch2 )
{
return ! traits_type::eq( ch1, ch2 );
}
};
// Compare two characters, disregarding case
template< typename CH >
struct ch_neq_nocase_t
{
typedef CH char_type;
typedef std::char_traits<char_type> traits_type;
static bool eval( register CH ch1, register CH ch2 )
{
return ! traits_type::eq( regex_toupper( ch1 ), regex_toupper( ch2 ) );
}
};
//
// helper functions for dealing with widths.
//
inline size_t width_add( size_t a, size_t b )
{
return ( size_t( -1 ) == a || size_t( -1 ) == b ? size_t( -1 ) : a + b );
}
inline size_t width_mult( size_t a, size_t b )
{
if( 0 == a || 0 == b )
return 0;
if( size_t( -1 ) == a || size_t( -1 ) == b )
return size_t( -1 );
return a * b;
}
inline bool operator==( width_type const & rhs, width_type const & lhs )
{
return ( rhs.m_min == lhs.m_min && rhs.m_max == lhs.m_max );
}
inline bool operator!=( width_type const & rhs, width_type const & lhs )
{
return ( rhs.m_min != lhs.m_min || rhs.m_max != lhs.m_max );
}
inline width_type operator+( width_type const & rhs, width_type const & lhs )
{
width_type width = { width_add( rhs.m_min, lhs.m_min ), width_add( rhs.m_max, lhs.m_max ) };
return width;
}
inline width_type operator*( width_type const & rhs, width_type const & lhs )
{
width_type width = { width_mult( rhs.m_min, lhs.m_min ), width_mult( rhs.m_max, lhs.m_max ) };
return width;
}
inline width_type & operator+=( width_type & rhs, width_type const & lhs )
{
rhs.m_min = width_add( rhs.m_min, lhs.m_min );
rhs.m_max = width_add( rhs.m_max, lhs.m_max );
return rhs;
}
inline width_type & operator*=( width_type & rhs, width_type const & lhs )
{
rhs.m_min = width_mult( rhs.m_min, lhs.m_min );
rhs.m_max = width_mult( rhs.m_max, lhs.m_max );
return rhs;
}
width_type const zero_width = { 0, 0 };
width_type const worst_width = { 0, size_t( -1 ) };
template< typename CI >
struct width_param
{
int cookie;
width_type const total_width;
std::vector<match_group_base<CI>*> & rggroups;
std::list<size_t> const & invisible_groups;
bool first_pass() const { return uninit_width() == total_width; }
width_param(
int cookie,
width_type const & total_width,
std::vector<match_group_base<CI>*> & rggroups,
std::list<size_t> const & invisible_groups )
: cookie( cookie ),
total_width( total_width ),
rggroups( rggroups ),
invisible_groups( invisible_groups )
{
}
private:
width_param & operator=( width_param const & );
};
// --------------------------------------------------------------------------
//
// Class: sub_expr
//
// Description: patterns are "compiled" into a directed graph of sub_expr
// structs. Matching is accomplished by traversing this graph.
//
// Methods: sub_expr - construct a sub_expr
// recursive_match_this_ - does this sub_expr match at the given location
// width_this - what is the width of this sub_expr
// ~sub_expr - recursively delete the sub_expr graph
// next - pointer to the next node in the graph
// next - pointer to the next node in the graph
// recursive_match_next_ - match the rest of the graph
// recursive_match_all_ - recursive_match_this_ and recursive_match_next_
// is_assertion - true if this sub_expr is a zero-width assertion
// get_width - find the width of the graph at this sub_expr
//
// Members: m_pnext - pointer to the next node in the graph
//
// History: 8/14/2000 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename CI >
class sub_expr : public sub_expr_base<CI>
{
sub_expr * m_pnext;
protected:
// Only derived classes can instantiate sub_expr's
sub_expr()
: m_pnext( NULL )
{
}
public:
typedef CI const_iterator;
typedef typename std::iterator_traits<CI>::value_type char_type;
typedef std::char_traits<char_type> traits_type;
virtual ~sub_expr()
{
delete m_pnext;
}
sub_expr ** pnext()
{
return & m_pnext;
}
sub_expr const * next() const
{
return m_pnext;
}
virtual sub_expr<CI> * quantify( size_t, size_t, bool, regex_arena & )
{
throw bad_regexpr( "sub-expression cannot be quantified" );
}
// Match this object and all subsequent objects
// If recursive_match_all_ returns false, it must not change any of param's state
virtual bool recursive_match_all_( match_param<CI> & param, CI icur ) const
{
return ( recursive_match_this_( param, icur ) && recursive_match_next_( param, icur, false_t() ) );
}
virtual bool recursive_match_all_c( match_param<CI> & param, CI icur ) const // for C-style strings
{
return ( recursive_match_this_c( param, icur ) && recursive_match_next_( param, icur, true_t() ) );
}
// match this object only
virtual bool recursive_match_this_( match_param<CI> &, CI & ) const
{
return true;
}
virtual bool recursive_match_this_c( match_param<CI> &, CI & ) const // for C-style strings
{
return true;
}
// Match all subsequent objects
template< typename CSTRINGS >
bool recursive_match_next_( match_param<CI> & param, CI icur, CSTRINGS ) const
{
return ( m_pnext ) ? m_pnext->recursive_match_all_( param, icur, CSTRINGS() ) :
! ( param.no0len && param.istart == icur );
}
virtual bool iterative_match_this_( match_param<CI> & param ) const
{
param.next = next();
return true;
}
virtual bool iterative_match_this_c( match_param<CI> & param ) const // for C-style strings
{
param.next = next();
return true;
}
virtual bool iterative_rematch_this_( match_param<CI> & ) const
{
return false;
}
virtual bool iterative_rematch_this_c( match_param<CI> & ) const // for C-style strings
{
return false;
}
virtual bool is_assertion() const
{
return false;
}
width_type get_width( width_param<CI> & param )
{
width_type temp_width = width_this( param );
if( m_pnext )
temp_width += m_pnext->get_width( param );
return temp_width;
}
virtual width_type width_this( width_param<CI> & ) = 0;
template< typename CSTRINGS >
bool iterative_match_this_( match_param<CI> & param, CSTRINGS ) const
{ return sub_expr_base<CI>::iterative_match_this_( param, CSTRINGS() ); }
template< typename CSTRINGS >
bool iterative_rematch_this_( match_param<CI> & param, CSTRINGS ) const
{ return sub_expr_base<CI>::iterative_rematch_this_( param, CSTRINGS() ); }
template< typename CSTRINGS >
bool recursive_match_all_( match_param<CI> & param, CI icur, CSTRINGS ) const
{ return sub_expr_base<CI>::recursive_match_all_( param, icur, CSTRINGS() ); }
};
// Base class for sub-expressions which are zero-width
// ( i.e., assertions eat no characters during matching )
// Assertions cannot be quantified.
template< typename CI >
class assertion : public sub_expr<CI>
{
public:
typedef typename sub_expr<CI>::const_iterator const_iterator;
typedef typename sub_expr<CI>::char_type char_type;
virtual bool is_assertion() const
{ return true; }
virtual width_type width_this( width_param<CI> & )
{ return zero_width; }
};
template< typename CI, typename OP >
class assert_op : public assertion<CI>
{
public:
virtual bool recursive_match_all_( match_param<CI> & param, CI icur ) const
{
return ( assert_op::recursive_match_this_( param, icur ) && recursive_match_next_( param, icur, false_t() ) );
}
virtual bool recursive_match_all_c( match_param<CI> & param, CI icur ) const
{
return ( assert_op::recursive_match_this_c( param, icur ) && recursive_match_next_( param, icur, true_t() ) );
}
virtual bool recursive_match_this_( match_param<CI> & param, CI & icur ) const
{
typedef typename OP::template rebind<false_t>::other op_t;
return op_t::eval( param, icur );
}
virtual bool recursive_match_this_c( match_param<CI> & param, CI & icur ) const
{
typedef typename OP::template rebind<true_t>::other op_t;
return op_t::eval( param, icur );
}
virtual bool iterative_match_this_( match_param<CI> & param ) const
{
param.next = next();
typedef typename OP::template rebind<false_t>::other op_t;
return op_t::eval( param, param.icur );
}
virtual bool iterative_match_this_c( match_param<CI> & param ) const
{
param.next = next();
typedef typename OP::template rebind<true_t>::other op_t;
return op_t::eval( param, param.icur );
}
};
template< typename CI >
inline assertion<CI> * create_bos( REGEX_FLAGS, regex_arena & arena )
{
return new( arena ) assert_op<CI, bos_t<true_t> >();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -