📄 regexpr2.cpp
字号:
virtual width_type width_this( width_param<IterT> & ) = 0;
virtual bool peek_this( peek_param<char_type> & ) const
{
return false;
}
};
// An object of type end_of_pattern is used to mark the
// end of the pattern. (Duh!) It is responsible for ending
// the recursion, or for letting the search continue if
// the match is zero-width and we are trying to find a
// non-zero-width match
template< typename IterT >
class end_of_pattern : public sub_expr<IterT>
{
bool _do_match_this( match_param<IterT> & param, IterT icur ) const
{
return ! param.m_no0len || param.m_imatchbegin != icur;
}
public:
virtual bool recursive_match_all_s( match_param<IterT> & param, IterT icur ) const
{
return _do_match_this( param, icur );
}
virtual bool recursive_match_all_c( match_param<IterT> & param, IterT icur ) const // for C-style strings
{
return _do_match_this( param, icur );
}
virtual bool iterative_match_this_s( match_param<IterT> & param ) const
{
param.m_pnext = 0;
return _do_match_this( param, param.m_icur );
}
virtual bool iterative_match_this_c( match_param<IterT> & param ) const // for C-style strings
{
param.m_pnext = 0;
return _do_match_this( param, param.m_icur );
}
virtual width_type width_this( width_param<IterT> & )
{
return zero_width;
}
};
// Base class for sub-expressions which are zero-width
// ( i.e., assertions eat no characters during matching )
// Assertions cannot be quantified.
template< typename IterT >
class assertion : public sub_expr<IterT>
{
public:
virtual bool is_assertion() const
{
return true;
}
virtual width_type width_this( width_param<IterT> & )
{
return zero_width;
}
virtual bool peek_this( peek_param<char_type> & peek ) const
{
return this->next()->peek_this( peek );
}
};
template< typename OpT, typename OpCT >
struct opwrap
{
typedef OpT op_type;
typedef OpCT opc_type;
};
#define REGEX_OP(x) opwrap< x<false_t>, x<true_t> >
template< typename IterT, typename OpWrapT >
class assert_op : public assertion<IterT>
{
public:
virtual bool recursive_match_all_s( match_param<IterT> & param, IterT icur ) const
{
return ( assert_op::recursive_match_this_s( param, icur ) && this->recursive_match_next( param, icur, false_t() ) );
}
virtual bool recursive_match_all_c( match_param<IterT> & param, IterT icur ) const
{
return ( assert_op::recursive_match_this_c( param, icur ) && this->recursive_match_next( param, icur, true_t() ) );
}
virtual bool recursive_match_this_s( match_param<IterT> & param, IterT & icur ) const
{
return OpWrapT::op_type::eval( param, icur );
}
virtual bool recursive_match_this_c( match_param<IterT> & param, IterT & icur ) const
{
return OpWrapT::opc_type::eval( param, icur );
}
virtual bool iterative_match_this_s( match_param<IterT> & param ) const
{
param.m_pnext = this->next();
return OpWrapT::op_type::eval( param, param.m_icur );
}
virtual bool iterative_match_this_c( match_param<IterT> & param ) const
{
param.m_pnext = this->next();
return OpWrapT::opc_type::eval( param, param.m_icur );
}
};
template< typename IterT >
inline assertion<IterT> * create_bos( REGEX_FLAGS, regex_arena & arena )
{
return new( arena ) assert_op<IterT, REGEX_OP(bos_t) >();
}
template< typename IterT >
inline assertion<IterT> * create_eos( REGEX_FLAGS, regex_arena & arena )
{
return new( arena ) assert_op<IterT, REGEX_OP(peos_t) >();
}
template< typename IterT >
inline assertion<IterT> * create_eoz( REGEX_FLAGS, regex_arena & arena )
{
return new( arena ) assert_op<IterT, REGEX_OP(eos_t) >();
}
template< typename IterT >
inline assertion<IterT> * create_bol( REGEX_FLAGS flags, regex_arena & arena )
{
switch( MULTILINE & flags )
{
case 0:
return new( arena ) assert_op<IterT, REGEX_OP(bos_t) >();
case MULTILINE:
return new( arena ) assert_op<IterT, REGEX_OP(bol_t) >();
default:
REGEX_ASSERT(false);
return 0;
}
}
template< typename IterT >
inline assertion<IterT> * create_eol( REGEX_FLAGS flags, regex_arena & arena )
{
switch( MULTILINE & flags )
{
case 0:
return new( arena ) assert_op<IterT, REGEX_OP(peos_t) >();
case MULTILINE:
return new( arena ) assert_op<IterT, REGEX_OP(eol_t) >();
default:
REGEX_ASSERT(false);
return 0;
}
}
template< typename IterT, typename SubExprT = sub_expr<IterT> >
class match_wrapper : public sub_expr<IterT>
{
match_wrapper & operator=( match_wrapper const & );
public:
match_wrapper( SubExprT * psub )
: m_psub( psub )
{
}
virtual ~match_wrapper()
{
_cleanup();
}
virtual width_type width_this( width_param<IterT> & param )
{
return m_psub->width_this( param );
}
virtual bool peek_this( peek_param<char_type> & peek ) const
{
return m_psub->peek_this( peek );
}
protected:
void _cleanup()
{
delete m_psub;
m_psub = 0;
}
SubExprT * m_psub;
};
template< typename IterT, typename SubExprT = sub_expr<IterT> >
class match_quantifier : public match_wrapper<IterT, SubExprT>
{
match_quantifier & operator=( match_quantifier const & );
public:
match_quantifier( SubExprT * psub, size_t lbound, size_t ubound )
: match_wrapper<IterT, SubExprT>( psub )
, m_lbound( lbound )
, m_ubound( ubound )
{
}
virtual width_type width_this( width_param<IterT> & param )
{
width_type this_width = match_wrapper<IterT, SubExprT>::width_this( param );
width_type quant_width = { m_lbound, m_ubound };
return this_width * quant_width;
}
virtual bool peek_this( peek_param<char_type> & peek ) const
{
return 0 != m_lbound && this->m_psub->peek_this( peek );
}
protected:
size_t const m_lbound;
size_t const m_ubound;
};
template< typename IterT, typename SubExprT >
class atom_quantifier : public match_quantifier<IterT, SubExprT>
{
atom_quantifier & operator=( atom_quantifier const & );
public:
atom_quantifier( SubExprT * psub, size_t lbound, size_t ubound )
: match_quantifier<IterT, SubExprT>( psub, lbound, ubound )
{
}
protected:
void _push_frame( unsafe_stack * pstack, IterT curr, size_t count ) const
{
std::pair<IterT, size_t> p( curr, count );
pstack->push( p );
}
void _pop_frame( match_param<IterT> & param ) const
{
std::pair<IterT, size_t> p;
param.m_pstack->pop( p );
param.m_icur = p.first;
}
};
template< typename IterT, typename SubExprT >
class max_atom_quantifier : public atom_quantifier<IterT, SubExprT>
{
max_atom_quantifier & operator=( max_atom_quantifier const & );
public:
max_atom_quantifier( SubExprT * psub, size_t lbound, size_t ubound )
: atom_quantifier<IterT, SubExprT>( psub, lbound, ubound )
{
}
// Why a macro instead of a template, you ask? Performance. Due to a known
// bug in the VC7 inline heuristic, I cannot get VC7 to inline the calls to
// m_psub methods unless I use these macros. And the performance win is
// nothing to sneeze at. It's on the order of a 25% speed up to use a macro
// here instead of a template.
#define DECLARE_RECURSIVE_MATCH_ALL(CSTRINGS,EXT) \
virtual bool recursive_match_all ## EXT( match_param<IterT> & param, IterT icur ) const \
{ \
typedef typename std::iterator_traits<IterT>::difference_type diff_type; \
/* In an ideal world, ibegin and cdiff would be members of a union */ \
/* to conserve stack, but I don't know if IterT is a POD type or not. */ \
IterT ibegin = icur; \
diff_type cdiff = 0; /* must be a signed integral type */ \
size_t cmatches = 0; \
/* greedily match as much as we can*/ \
if( this->m_ubound && this->m_psub->SubExprT::recursive_match_this ## EXT( param, icur ) ) \
{ \
if( 0 == ( cdiff = -std::distance( ibegin, icur ) ) ) \
return this->recursive_match_next( param, icur, CSTRINGS() ); \
while( ++cmatches < this->m_ubound && this->m_psub->SubExprT::recursive_match_this ## EXT( param, icur ) )\
{} \
} \
if( this->m_lbound > cmatches ) \
return false; \
/* try matching the rest of the pattern, and back off if necessary */ \
for( ; ; --cmatches, std::advance( icur, cdiff ) ) \
{ \
if( this->recursive_match_next( param, icur, CSTRINGS() ) ) \
return true; \
if( this->m_lbound == cmatches ) \
return false; \
} \
}
#define DECLARE_ITERATIVE_MATCH_THIS(EXT) \
virtual bool iterative_match_this ## EXT( match_param<IterT> & param ) const \
{ \
IterT ibegin = param.m_icur; \
size_t cmatches = 0; \
if( this->m_ubound && this->m_psub->SubExprT::iterative_match_this ## EXT( param ) ) \
{ \
if( 0 == std::distance( ibegin, param.m_icur ) ) \
{ \
cmatches = this->m_lbound; \
} \
else \
{ \
while( ++cmatches < this->m_ubound && this->m_psub->SubExprT::iterative_match_this ## EXT( param ) )\
{} \
} \
} \
if( cmatches >= this->m_lbound ) \
{ \
this->_push_frame( param.m_pstack, ibegin, cmatches ); \
param.m_pnext = this->next(); \
return true; \
} \
param.m_icur = ibegin; \
return false; \
}
#define DECLARE_ITERATIVE_REMATCH_THIS(EXT) \
virtual bool iterative_rematch_this ## EXT( match_param<IterT> & param ) const \
{ \
typedef std::pair<IterT, size_t> top_type; \
size_t & cmatches = REGEX_VC6( param.m_pstack->top( type2type<top_type>() ).second ) \
REGEX_NVC6( param.m_pstack->template top<top_type>().second ); \
if( this->m_lbound != cmatches ) \
{ \
--cmatches; \
this->m_psub->SubExprT::iterative_rematch_this ## EXT( param ); \
param.m_pnext = this->next(); \
return true; \
} \
this->_pop_frame( param ); \
return false; \
}
DECLARE_RECURSIVE_MATCH_ALL(false_t,_s)
DECLARE_RECURSIVE_MATCH_ALL(true_t,_c)
DECLARE_ITERATIVE_MATCH_THIS(_s)
DECLARE_ITERATIVE_MATCH_THIS(_c)
DECLARE_ITERATIVE_REMATCH_THIS(_s)
DECLARE_ITERATIVE_REMATCH_THIS(_c)
#undef DECLARE_RECURSIVE_MATCH_ALL
#undef DECLARE_ITERATIVE_MATCH_THIS
#undef DECLARE_ITERATIVE_REMATCH_THIS
};
template< typename IterT, typename SubExprT >
class min_atom_quantifier : public atom_quantifier<IterT, SubExprT>
{
min_atom_quantifier & operator=( min_atom_quantifier const & );
public:
min_atom_quantifier( SubExprT * psub, size_t lbound, size_t ubound )
: atom_quantifier<IterT, SubExprT>( psub, lbound, ubound )
{
}
// Why a macro instead of a template, you ask? Performance. Due to a known
// bug in the VC7 inline heuristic, I cannot get VC7 to inline the calls to
// m_psub methods unless I use these macros. And the performance win is
// nothing to sneeze at. It's on the order of a 25% speed up to use a macro
// here instead of a template.
#define DECLARE_RECURSIVE_MATCH_ALL(CSTRINGS,EXT) \
virtual bool recursive_match_all ## EXT( match_param<IterT> & param, IterT icur ) const \
{ \
IterT icur_tmp = icur; \
size_t cmatches = 0; \
if( this->m_psub->SubExprT::recursive_match_this ## EXT( param, icur_tmp ) ) \
{ \
if( icur_tmp == icur ) \
return this->recursive_match_next( param, icur, CSTRINGS() ); \
if( this->m_lbound ) \
{ \
icur = icur_tmp; \
++cmatches; \
} \
for( ; cmatches < this->m_lbound; ++cmatches ) \
{ \
if( ! this->m_psub->SubExprT::recursive_match_this ## EXT( param, icur ) ) \
return false; \
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -