📄 syntax2.h
字号:
{
m_str = node.m_str;
m_rgcharsets[0] = node.m_rgcharsets[0];
m_rgcharsets[1] = node.m_rgcharsets[1];
return *this;
}
void set( std::basic_string<CH> const & str )
{
clear();
m_str = str;
}
void clear()
{
std::basic_string<CH>().swap( m_str );
free_charset( m_rgcharsets[0] );
free_charset( m_rgcharsets[1] );
m_rgcharsets[0] = m_rgcharsets[1] = NULL;
}
};
template< typename CH >
class charset_map
{
std::map<CH, charset_map_node<CH> > m_map;
public:
typedef typename std::map<CH, charset_map_node<CH> >::iterator iterator;
~charset_map()
{
for( iterator iter = m_map.begin(); m_map.end() != iter; ++iter )
iter->second.clear();
}
charset_map_node<CH> & operator[]( CH ch ) { return m_map[ ch ]; }
iterator begin() { return m_map.begin(); }
iterator end() { return m_map.end(); }
iterator find( CH ch ) { return m_map.find( ch ); }
void erase( iterator iter ) { m_map.erase( iter ); }
};
inline bool regex_isspace( char ch )
{
return 0 != isspace( ch );
}
inline bool regex_isspace( wchar_t wch )
{
return 0 != iswspace( wch );
}
} // namespace detail
//
// The perl_syntax class encapsulates the Perl 5 regular expression syntax. It is
// used as a template parameter to basic_rpattern. To customize regex syntax, create
// your own syntax class and use it as a template parameter instead.
//
class perl_syntax_base
{
protected:
perl_syntax_base()
{
}
static TOKEN const s_rgreg[ UCHAR_MAX + 1 ];
static TOKEN const s_rgescape[ UCHAR_MAX + 1 ];
static TOKEN look_up( char ch, TOKEN const rg[] )
{
return rg[ static_cast<unsigned char>( ch ) ];
}
static TOKEN look_up( wchar_t ch, TOKEN const rg[] )
{
return UCHAR_MAX < ch ? NO_TOKEN : rg[ static_cast<unsigned char>( ch ) ];
}
};
// --------------------------------------------------------------------------
//
// Class: perl_syntax
//
// Description: Module that encapsulates the Perl syntax
//
// Methods: eat_whitespace -
// min_quant -
// perl_syntax -
// perl_syntax -
// set_flags -
// get_flags -
// reg_token -
// quant_token -
// charset_token -
// subst_token -
// ext_token -
// invalid_charset -
// register_intrinsic_charset -
// _invalid_charset -
// _invalid_charset -
//
// Members: m_flags -
// s_charset_map -
//
// Typedefs: iterator -
// const_iterator -
// char_type -
//
// History: 11/16/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename CH >
class perl_syntax : protected perl_syntax_base
{
public:
typedef typename std::basic_string<CH>::iterator iterator;
typedef typename std::basic_string<CH>::const_iterator const_iterator;
typedef CH char_type;
template< typename CH2 > struct rebind { typedef perl_syntax<CH2> other; };
private:
REGEX_FLAGS m_flags;
const_iterator eat_whitespace( iterator & icur, const_iterator iend )
{
if( m_flags & EXTENDED )
{
while( iend != icur && ( REGEX_CHAR(CH,'#') == *icur || detail::regex_isspace( *icur ) ) )
{
if( REGEX_CHAR(CH,'#') == *icur++ )
{
while( iend != icur && REGEX_CHAR(CH,'\n') != *icur++ );
}
else
{
for( ; iend != icur && detail::regex_isspace( *icur ); ++icur );
}
}
}
return icur;
}
bool min_quant( iterator & icur, const_iterator iend )
{
return ( iend != eat_whitespace( ++icur, iend ) && REGEX_CHAR(CH,'?') == *icur ? ( ++icur, true ) : false );
}
public:
perl_syntax( REGEX_FLAGS flags )
: m_flags( flags )
{
}
perl_syntax( perl_syntax<CH> const & sy )
: m_flags( sy.m_flags )
{
}
void set_flags( REGEX_FLAGS flags )
{
m_flags = flags;
}
REGEX_FLAGS get_flags() const
{
return m_flags;
}
TOKEN reg_token( iterator & icur, const_iterator iend )
{
assert( iend != icur );
if( iend == eat_whitespace( icur, iend ) )
return NO_TOKEN;
TOKEN tok = look_up( *icur, s_rgreg );
if( tok )
++icur;
if( ESCAPE == tok && iend != icur )
{
tok = look_up( *icur, s_rgescape );
if( tok )
++icur;
else
tok = ESCAPE;
}
return tok;
}
TOKEN quant_token( iterator & icur, const_iterator iend )
{
assert( iend != icur );
if( iend == eat_whitespace( icur, iend ) )
return NO_TOKEN;
TOKEN tok = NO_TOKEN;
switch( *icur )
{
case REGEX_CHAR(CH,'*'):
tok = min_quant( icur, iend ) ? ZERO_OR_MORE_MIN : ZERO_OR_MORE;
break;
case REGEX_CHAR(CH,'+'):
tok = min_quant( icur, iend ) ? ONE_OR_MORE_MIN : ONE_OR_MORE;
break;
case REGEX_CHAR(CH,'?'):
tok = min_quant( icur, iend ) ? ZERO_OR_ONE_MIN : ZERO_OR_ONE;
break;
case REGEX_CHAR(CH,'}'):
tok = min_quant( icur, iend ) ? END_RANGE_MIN : END_RANGE;
break;
case REGEX_CHAR(CH,'{'):
tok = BEGIN_RANGE;
++icur;
break;
case REGEX_CHAR(CH,','):
tok = RANGE_SEPARATOR;
++icur;
break;
}
return tok;
}
TOKEN charset_token( iterator & icur, const_iterator iend )
{
assert( iend != icur );
TOKEN tok = NO_TOKEN;
switch( *icur )
{
case REGEX_CHAR(CH,'-'):
tok = CHARSET_RANGE;
++icur;
break;
case REGEX_CHAR(CH,'^'):
tok = CHARSET_NEGATE;
++icur;
break;
case REGEX_CHAR(CH,']'):
tok = CHARSET_END;
++icur;
break;
case REGEX_CHAR(CH,'\\'):
tok = CHARSET_ESCAPE;
if( iend == ++icur )
break;
switch( *icur )
{
case REGEX_CHAR(CH,'b'):
tok = CHARSET_BACKSPACE;
++icur;
break;
case REGEX_CHAR(CH,'d'):
tok = ESC_DIGIT;
++icur;
break;
case REGEX_CHAR(CH,'D'):
tok = ESC_NOT_DIGIT;
++icur;
break;
case REGEX_CHAR(CH,'s'):
tok = ESC_SPACE;
++icur;
break;
case REGEX_CHAR(CH,'S'):
tok = ESC_NOT_SPACE;
++icur;
break;
case REGEX_CHAR(CH,'w'):
tok = ESC_WORD;
++icur;
break;
case REGEX_CHAR(CH,'W'):
tok = ESC_NOT_WORD;
++icur;
break;
}
break;
case REGEX_CHAR(CH,'['):
if( REGEX_CHAR(CH,':') == *( ++icur )-- )
{
for( size_t i=0; !tok && i < detail::g_cposix_charsets; ++i )
{
if( detail::is_posix_charset<const_iterator>( icur, iend, detail::g_rgposix_charsets[i].szcharset ) )
{
tok = TOKEN( CHARSET_ALNUM + i );
std::advance( icur, detail::g_rgposix_charsets[i].cchars );
}
}
}
break;
}
return tok;
}
TOKEN subst_token( iterator & icur, const_iterator iend )
{
assert( iend != icur );
TOKEN tok = NO_TOKEN;
switch( *icur )
{
case REGEX_CHAR(CH,'\\'):
tok = SUBST_ESCAPE;
if( iend != ++icur )
switch( *icur )
{
case REGEX_CHAR(CH,'Q'):
tok = SUBST_QUOTE_META_ON;
++icur;
break;
case REGEX_CHAR(CH,'U'):
tok = SUBST_UPPER_ON;
++icur;
break;
case REGEX_CHAR(CH,'u'):
tok = SUBST_UPPER_NEXT;
++icur;
break;
case REGEX_CHAR(CH,'L'):
tok = SUBST_LOWER_ON;
++icur;
break;
case REGEX_CHAR(CH,'l'):
tok = SUBST_LOWER_NEXT;
++icur;
break;
case REGEX_CHAR(CH,'E'):
tok = SUBST_ALL_OFF;
++icur;
break;
}
break;
case REGEX_CHAR(CH,'$'):
tok = SUBST_BACKREF;
if( iend != ++icur )
switch( *icur )
{
case REGEX_CHAR(CH,'&'):
tok = SUBST_MATCH;
++icur;
break;
case REGEX_CHAR(CH,'`'):
tok = SUBST_PREMATCH;
++icur;
break;
case REGEX_CHAR(CH,'\''):
tok = SUBST_POSTMATCH;
++icur;
break;
}
break;
}
return tok;
}
TOKEN ext_token( iterator & icur, const_iterator iend )
{
assert( iend != icur );
if( iend == eat_whitespace( icur, iend ) )
return NO_TOKEN;
bool finclude;
TOKEN tok = NO_TOKEN;
if( REGEX_CHAR(CH,'?') == *icur )
{
tok = EXT_UNKNOWN;
++icur;
if( m_flags & EXTENDED )
for( ; iend != icur && detail::regex_isspace( *icur ); ++icur );
if( iend != icur )
{
switch( *icur )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -