⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syntax2.h

📁 代理服务器原代码
💻 H
📖 第 1 页 / 共 3 页
字号:
    {
        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 + -