📄 regexpr2.h
字号:
//+---------------------------------------------------------------------------
//
// Copyright ( C ) Microsoft Corporation, 1994 - 2002.
//
// File: regexpr2.h
//
// Contents: classes for regular expression pattern matching a-la perl
//
// Classes: basic_rpattern_base
//
// Functions: rpattern::match
// rpattern::substitute
// match_results::cbackrefs
// match_results::backref
// match_results::all_backrefs
// match_results::backref_str
//
// Author: Eric Niebler ( ericne@microsoft.com )
//
//----------------------------------------------------------------------------
#ifndef REGEXPR_H
#define REGEXPR_H
#ifdef _MSC_VER
// warning C4097: typedef-name '' used as synonym for class-name
// warning C4189: local variable is initialized but not referenced
// warning C4514: '' : unreferenced inline function has been removed
// warning C4702: unreachable code
// warning C4710: function 'blah' not inlined
// warning C4786: identifier was truncated to '255' characters in the debug information
# pragma warning( push )
# pragma warning( disable : 4097 4189 4514 4702 4710 4786 )
extern "C" unsigned long __cdecl _exception_code();
# define REGEX_STACK_OVERFLOW 0xC00000FDL
# if _MSC_VER < 1300
extern "C" int __cdecl _resetstkoflw(void);
# else
# include <malloc.h> // for _resetstkoflw
# endif
#endif
#include <list>
#include <iosfwd>
#include <string>
#include <vector>
#include "syntax2.h"
#include "restack.h"
namespace regex
{
// This is the default alignment for the unsafe heterogeneous stack.
// If you are getting a compiler error in one of the unsafe_stack
// methods, then compile with -DREGEX_STACK_ALIGNMENT=16 or 32
#ifndef REGEX_STACK_ALIGNMENT
# define REGEX_STACK_ALIGNMENT sizeof( void* )
#endif
#ifndef REGEX_DEBUG
# if defined(DEBUG) | defined(_DEBUG) | defined(DBG)
# define REGEX_DEBUG 1
# else
# define REGEX_DEBUG 0
# endif
#endif
namespace detail
{
#if REGEX_DEBUG
typedef hetero_stack<REGEX_STACK_ALIGNMENT,true,true,32,0> unsafe_stack;
#else
typedef hetero_stack<REGEX_STACK_ALIGNMENT,false,true,4096,1024> unsafe_stack;
#endif
// Used to initialize variables with the same value they would have
// if they were initialized as a static global. ( Ptrs get NULL,
// integer types get 0, etc, etc )
template<typename T> struct static_init { static T const value; };
template<typename T> T const static_init<T>::value = T();
//
// Forward declarations
//
template< typename CI > class sub_expr;
template< typename CI > class match_group_base;
template< typename CI > class basic_rpattern_base_impl;
template< typename CI > struct match_param;
template< typename CI > struct sub_expr_base;
template< typename CI > struct matcher_helper;
} // namespace detail
// --------------------------------------------------------------------------
//
// Class: width_type
//
// Description: represents the width of a sub-expression
//
// Members: m_min - smallest number of characters a sub-expr can span
// m_max - largest number of characters a sub-expr can span
//
// History: 8/14/2000 - ericne - Created
//
// --------------------------------------------------------------------------
struct width_type
{
size_t m_min;
size_t m_max;
};
inline width_type const uninit_width()
{
width_type const width = { size_t( -1 ), size_t( -1 ) };
return width;
}
// Helper function for processing escape sequences
template< typename CH, typename TR, typename AL >
void process_escapes( std::basic_string<CH, TR, AL> & str, bool fPattern = false ); //throw()
// --------------------------------------------------------------------------
//
// Class: backref_tag
//
// Description: Struct which contains a back-reference. It is a template
// on the iterator type.
//
// Methods: backref_tag - c'tor
// operator bool - so that if( br ) is true if this br matched
// operator! - inverse of operator bool()
//
// Members: reserved - move along, nothing to see here
//
// History: 8/9/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename CI >
class backref_tag : public std::pair<CI, CI>
{
struct detail_t { detail_t * d; };
template< typename OSTREAM >
void REGEX_CDECL _do_print( OSTREAM & sout, ... ) const
{
typedef typename OSTREAM::char_type CH;
typedef typename OSTREAM::traits_type TR;
std::ostreambuf_iterator<CH, TR> iout( sout );
for( CI iter = first; iter != second; ++iter, ++iout )
*iout = *iter;
}
template< typename OSTREAM >
void _do_print( OSTREAM & sout, typename OSTREAM::char_type const * ) const
{
sout.write( first, static_cast<std::streamsize>( std::distance( first, second ) ) );
}
public:
typedef CI iterator_type;
typedef typename std::iterator_traits<CI>::value_type char_type;
typedef std::basic_string<char_type> string_type;
explicit backref_tag(
CI i1 = detail::static_init<CI>::value,
CI i2 = detail::static_init<CI>::value )
: std::pair<CI, CI>( i1, i2 ),
matched( false ),
reserved1( i1 ),
reserved2( 0 ),
reserved3( false ),
reserved4( detail::static_init<CI>::value ),
reserved5( detail::static_init<CI>::value )
{
}
CI begin() const
{
return first;
}
CI end() const
{
return second;
}
string_type const str() const
{
return matched ? string_type( first, second ) : string_type();
}
// Use the "safe bool" idiom. This allows implicit conversion to bool,
// but not to int. It also disallows conversion to void*.
typedef detail_t * detail_t::* bool_type;
operator bool_type() const //throw()
{
return matched ? &detail_t::d : 0;
}
bool operator!() const //throw()
{
return ! matched;
}
template< typename CH, typename TR >
std::basic_ostream<CH, TR> & print( std::basic_ostream<CH, TR> & sout ) const
{
_do_print( sout, CI() );
return sout;
}
bool matched;
CI reserved1; // used for internal book-keeping
size_t reserved2; // used for internal book-keeping
bool reserved3; // used for internal book-keeping
CI reserved4; // used for internal book-keeping
CI reserved5; // used for internal book-keeping
};
// --------------------------------------------------------------------------
//
// Class: basic_match_results
//
// Description: Use this structure for returning match/substitute results
// out from the match()/substitute() methods.
//
// Methods: cbackrefs -
// backref -
// all_backrefs -
// rlength -
//
// Members: m_rgbackrefs -
//
// Typedefs: const_iterator -
// backref_type -
// backref_vector -
//
// History: 8/8/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename CI >
struct basic_match_results
{
typedef CI const_iterator;
typedef backref_tag< const_iterator > backref_type;
typedef std::vector< backref_type > backref_vector;
friend struct detail::matcher_helper<CI>;
virtual ~basic_match_results()
{
}
size_t cbackrefs() const //throw()
{
return m_rgbackrefs.size();
}
backref_type const & backref( size_t cbackref ) const //throw( std::out_of_range )
{
return m_rgbackrefs.at( cbackref );
}
backref_vector const & all_backrefs() const //throw()
{
return m_rgbackrefs;
}
size_t rstart( size_t cbackref = 0 ) const //throw( std::out_of_range )
{
return std::distance( ibegin, m_rgbackrefs.at( cbackref ).first );
}
size_t rlength( size_t cbackref = 0 ) const //throw( std::out_of_range )
{
return std::distance( m_rgbackrefs.at( cbackref ).first, m_rgbackrefs.at( cbackref ).second );
}
private:
backref_vector m_rgbackrefs;
CI ibegin;
};
template< typename CH >
struct basic_match_results_c : public basic_match_results<CH const *>
{
typedef basic_match_results<CH const *> base;
typedef typename base::const_iterator const_iterator;
typedef typename base::backref_type backref_type;
typedef typename base::backref_vector backref_vector;
};
template< typename CH, typename TR = std::char_traits<CH>, typename AL = std::allocator<CH> >
struct basic_subst_results : public basic_match_results<typename std::basic_string<CH, TR, AL>::const_iterator>
{
typedef basic_match_results<typename std::basic_string<CH, TR, AL>::const_iterator> base;
typedef typename base::const_iterator const_iterator;
typedef typename base::backref_type backref_type;
typedef typename base::backref_vector backref_vector;
typedef std::basic_string<CH, TR, AL> string_type;
friend struct detail::matcher_helper<const_iterator>;
basic_subst_results()
: m_pbackref_str( &m_backref_str )
{
}
string_type const & backref_str() const //throw()
{
return *m_pbackref_str;
}
private:
string_type m_backref_str;
string_type const * m_pbackref_str;
};
// The REGEX_MODE is a way of controlling how matching occurs.
enum REGEX_MODE
{
MODE_FAST, // Uses the fast, recursive algorithm. Could overflow stack.
MODE_SAFE, // Uses the slow, iterative algorithm. Can't overflow stack.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -