?? deelx.h
字號:
case RCHART('{'):
{
CBufferT <char> re;
// skip '{'
MoveNext();
// copy
while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('}'), 1))
{
re.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
MoveNext();
}
// skip '}'
MoveNext();
// read
int red;
char * str = re.GetBuffer();
if( ! ReadDec(str, nMin) )
red = 0;
else if( *str != ',' )
red = 1;
else
{
str ++;
if( ! ReadDec(str, nMax) )
red = 2;
else
red = 3;
}
// check
if(red <= 1 ) nMax = nMin;
if(red == 2 ) nMax = INT_MAX;
if(nMax < nMin) nMax = nMin;
}
break;
case RCHART('?'):
nMin = 0;
nMax = 1;
// skip '?'
MoveNext();
break;
case RCHART('*'):
nMin = 0;
nMax = INT_MAX;
// skip '*'
MoveNext();
break;
case RCHART('+'):
nMin = 1;
nMax = INT_MAX;
// skip '+'
MoveNext();
break;
default:
bIsQuantifier = 0;
break;
}
// do quantify
if(bIsQuantifier)
{
// 0 times
if(nMax == 0)
return GetStockElx(STOCKELX_EMPTY);
// fixed times
if(nMin == nMax)
{
if(curr == CHART_INFO(RCHART('?'), 1) || curr == CHART_INFO(RCHART('+'), 1))
MoveNext();
return Keep(new CRepeatElx(pSimple, nMin));
}
// range times
if(curr == CHART_INFO(RCHART('?'), 1))
{
MoveNext();
return Keep(new CReluctantElx(pSimple, nMin, nMax));
}
else if(curr == CHART_INFO(RCHART('+'), 1))
{
MoveNext();
return Keep(new CPossessiveElx(pSimple, nMin, nMax));
}
else
{
return Keep(new CGreedyElx(pSimple, nMin, nMax));
}
}
return pSimple;
}
template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildSimple(int & flags)
{
CBufferT <CHART> fixed;
while(curr != CHART_INFO(0, 1))
{
if(curr.type == 0)
{
if(next == CHART_INFO(RCHART('{'), 1) || next == CHART_INFO(RCHART('?'), 1) || next == CHART_INFO(RCHART('*'), 1) || next == CHART_INFO(RCHART('+'), 1))
{
if(fixed.GetSize() == 0)
{
fixed.Append(curr.ch, 1);
MoveNext();
}
break;
}
else
{
fixed.Append(curr.ch, 1);
MoveNext();
}
}
else if(curr.type == 1)
{
CHART vch = curr.ch;
// end of simple
if(vch == RCHART(')') || vch == RCHART('|'))
break;
// has fixed already
if(fixed.GetSize() > 0)
break;
// left parentheses
if(vch == RCHART('('))
{
return BuildRecursive(flags);
}
// char set
if( vch == RCHART('[') || vch == RCHART('.') || vch == RCHART('w') || vch == RCHART('W') ||
vch == RCHART('s') || vch == RCHART('S') || vch == RCHART('d') || vch == RCHART('D')
)
{
return BuildCharset(flags);
}
// boundary
if( vch == RCHART('^') || vch == RCHART('$') || vch == RCHART('A') || vch == RCHART('Z') || vch == RCHART('z') ||
vch == RCHART('b') || vch == RCHART('B') || vch == RCHART('G') // vch == RCHART('<') || vch == RCHART('>')
)
{
return BuildBoundary(flags);
}
// backref
if(vch == RCHART('\\') || vch == RCHART('k') || vch == RCHART('g'))
{
return BuildBackref(flags);
}
// treat vchar as char
fixed.Append(curr.ch, 1);
MoveNext();
}
}
if(fixed.GetSize() > 0)
return Keep(new CStringElxT <CHART> (fixed.GetBuffer(), fixed.GetSize(), flags & RIGHTTOLEFT, flags & IGNORECASE));
else
return GetStockElx(STOCKELX_EMPTY);
}
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildCharset(int & flags)
{
// char
CHART ch = curr.ch;
// skip
MoveNext();
switch(ch)
{
case RCHART('.'):
return GetStockElx(
flags & RIGHTTOLEFT ?
((flags & SINGLELINE) ? STOCKELX_DOT_ALL_RIGHTLEFT : STOCKELX_DOT_NOT_ALL_RIGHTLEFT) :
((flags & SINGLELINE) ? STOCKELX_DOT_ALL : STOCKELX_DOT_NOT_ALL)
);
case RCHART('w'):
return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_WORD_RIGHTLEFT : STOCKELX_WORD);
case RCHART('W'):
return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_WORD_RIGHTLEFT_NOT : STOCKELX_WORD_NOT);
case RCHART('s'):
return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_SPACE_RIGHTLEFT : STOCKELX_SPACE);
case RCHART('S'):
return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_SPACE_RIGHTLEFT_NOT : STOCKELX_SPACE_NOT);
case RCHART('d'):
return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_DIGITAL_RIGHTLEFT : STOCKELX_DIGITAL);
case RCHART('D'):
return GetStockElx(flags & RIGHTTOLEFT ? STOCKELX_DIGITAL_RIGHTLEFT_NOT : STOCKELX_DIGITAL_NOT);
case RCHART('['):
{
CRangeElxT <CHART> * pRange;
// create
if(curr == CHART_INFO(RCHART(':'), 1))
{
CBufferT <char> posix;
do {
posix.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
MoveNext();
}
while(curr.ch != RCHART(0) && curr != CHART_INFO(RCHART(']'), 1));
MoveNext(); // skip ']'
// posix
return Keep(new CPosixElxT <CHART> (posix.GetBuffer(), flags & RIGHTTOLEFT));
}
else if(curr == CHART_INFO(RCHART('^'), 1))
{
MoveNext(); // skip '^'
pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (flags & RIGHTTOLEFT, 0));
}
else
{
pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (flags & RIGHTTOLEFT, 1));
}
// parse
while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART(']'), 1))
{
ch = curr.ch;
if(curr.type == 1 && (
ch == RCHART('.') || ch == RCHART('w') || ch == RCHART('W') || ch == RCHART('s') || ch == RCHART('S') || ch == RCHART('d') || ch == RCHART('D') ||
(ch == RCHART('[') && next == CHART_INFO(RCHART(':'), 1))
))
{
pRange->m_embeds.Push(BuildCharset(flags));
}
else if(next == CHART_INFO(RCHART('-'), 1) && nex2.type == 0)
{
pRange->m_ranges.Push(ch); pRange->m_ranges.Push(nex2.ch);
// next
MoveNext();
MoveNext();
MoveNext();
}
else
{
pRange->m_chars.Push(ch);
// next
MoveNext();
}
}
// skip ']'
MoveNext();
if( flags & IGNORECASE )
{
CBufferT <CHART> & ranges = pRange->m_ranges;
int i, oldcount = ranges.GetSize() / 2;
for(i=0; i<oldcount; i++)
{
CHART newmin, newmax;
if( ranges[i*2] <= RCHART('Z') && ranges[i*2+1] >= RCHART('A') )
{
newmin = tolower( max(RCHART('A'), ranges[i*2 ]) );
newmax = tolower( min(RCHART('Z'), ranges[i*2+1]) );
if( newmin < ranges[i*2] || newmax > ranges[i*2+1] )
{
ranges.Push(newmin);
ranges.Push(newmax);
}
}
if( ranges[i*2] <= RCHART('z') && ranges[i*2+1] >= RCHART('a') )
{
newmin = toupper( max(RCHART('a'), ranges[i*2 ]) );
newmax = toupper( min(RCHART('z'), ranges[i*2+1]) );
if( newmin < ranges[i*2] || newmax > ranges[i*2+1] )
{
ranges.Push(newmin);
ranges.Push(newmax);
}
}
}
CBufferT <CHART> & chars = pRange->m_chars;
oldcount = chars.GetSize();
for(i=0; i<oldcount; i++)
{
if( isupper(chars[i]) && ! pRange->IsContainChar(tolower(chars[i])) )
chars.Push(tolower(chars[i]));
if( islower(chars[i]) && ! pRange->IsContainChar(toupper(chars[i])) )
chars.Push(toupper(chars[i]));
}
}
return pRange;
}
}
return GetStockElx(STOCKELX_EMPTY);
}
template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildRecursive(int & flags)
{
// skip '('
MoveNext();
if(curr == CHART_INFO(RCHART('?'), 1))
{
ElxInterface * pElx = 0;
// skip '?'
MoveNext();
int bNegative = 0;
CHART named_end = RCHART('>');
switch(curr.ch)
{
case RCHART('!'):
bNegative = 1;
case RCHART('='):
{
MoveNext(); // skip '!' or '='
pElx = Keep(new CAssertElx(BuildAlternative(flags & ~RIGHTTOLEFT), !bNegative));
}
break;
case RCHART('<'):
switch(next.ch)
{
case RCHART('!'):
bNegative = 1;
case RCHART('='):
MoveNext(); // skip '<'
MoveNext(); // skip '!' or '='
{
pElx = Keep(new CAssertElx(BuildAlternative(flags | RIGHTTOLEFT), !bNegative));
}
break;
default: // named group
break;
}
// break if assertion // else named
if(pElx != 0) break;
case RCHART('P'):
if(curr.ch == RCHART('P')) MoveNext(); // skip 'P'
case RCHART('\''):
if (curr.ch == RCHART('<' )) named_end = RCHART('>' );
else if(curr.ch == RCHART('\'')) named_end = RCHART('\'');
MoveNext(); // skip '<' or '\''
{
// named number
int nThisBackref = m_nNextNamed ++;
CListElx * pList = (CListElx *)Keep(new CListElx(flags & RIGHTTOLEFT));
CBracketElx * pleft = (CBracketElx *)Keep(new CBracketElx(-1, flags & RIGHTTOLEFT ? 1 : 0));
CBracketElx * pright = (CBracketElx *)Keep(new CBracketElx(-1, flags & RIGHTTOLEFT ? 0 : 1));
// save name
CBufferT <CHART> & name = pleft->m_szNamed;
CBufferT <char> num;
while(curr.ch != RCHART(0) && curr.ch != named_end)
{
name.Append(curr.ch, 1);
num .Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
MoveNext();
}
MoveNext(); // skip '>' or '\''
// check <num>
unsigned int number;
char * str = num.GetBuffer();
if( ReadDec(str, number) ? ( *str == '\0') : 0 )
{
pleft ->m_nnumber = number;
pright->m_nnumber = number;
name.Release();
}
// left, center, right
pList->m_elxlist.Push(pleft);
pList->m_elxlist.Push(BuildAlternative(flags));
pList->m_elxlist.Push(pright);
// for recursive
m_namedlist.Prepare(nThisBackref);
m_namedlist[nThisBackref] = pList;
pElx = pList;
}
break;
case RCHART('>'):
{
MoveNext(); // skip '>'
pElx = Keep(new CIndependentElx(BuildAlternative(flags)));
}
break;
case RCHART('R'):
MoveNext(); // skip 'R'
while(curr.ch != RCHART(0) && isspace(curr.ch)) MoveNext(); // skip space
if(curr.ch == RCHART('<') || curr.ch == RCHART('\''))
{
named_end = curr.ch == RCHART('<') ? RCHART('>') : RCHART('\'');
CDelegateElx * pDelegate = (CDelegateElx *)Keep(new CDelegateElx(-3));
MoveNext(); // skip '<' or '\\'
// save name
CBufferT <CHART> & name = pDelegate->m_szNamed;
CBufferT <char> num;
while(curr.ch != RCHART(0) && curr.ch != named_end)
{
name.Append(curr.ch, 1);
num .Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
MoveNext();
}
MoveNext(); // skip '>' or '\''
// check <num>
unsigned int number;
char * str = num.GetBuffer();
if( ReadDec(str, number) ? ( *str == '\0') : 0 )
{
pDelegate->m_ndata = number;
name.Release();
}
m_recursivelist.Push(pDelegate);
pElx = pDelegate;
}
else
{
CBufferT <char> rto;
while(curr.ch != RCHART(0) && curr.ch != RCHART(')'))
{
rto.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
MoveNext();
}
unsigned int rtono = 0;
char * str = rto.GetBuffer();
ReadDec(str, rtono);
CDelegateElx * pDelegate = (CDelegateElx *)Keep(new CDelegateElx(rtono));
m_recursivelist.Push(pDelegate);
pElx = pDelegate;
}
break;
case RCHART('('):
{
CConditionElx * pConditionElx = (CConditionElx *)Keep(new CConditionElx());
// condition
ElxInterface * & pCondition = pConditionElx->m_pelxask;
if(next == CHART_INFO(RCHART('?'), 1))
{
pCondition = BuildRecursive(flags);
}
else // named, assert or number
{
MoveNext(); // skip '('
int pos0 = curr.pos;
// save elx condition
pCondition = Keep(new CAssertElx(BuildAlternative(flags), 1));
// save name
pConditionElx->m_szNamed.Append(m_pattern.GetBuffer() + pos0, curr.pos - pos0, 1);
// save number
CBufferT <char> numstr;
while(pos0 < curr.pos)
{
CHART ch = m_pattern[pos0];
numstr.Append(((ch & (CHART)0xff) == ch) ? (char)ch : 0, 1);
pos0 ++;
}
unsigned int number;
char * str = numstr.GetBuffer();
// valid group number
if( ReadDec(str, number) ? ( *str == '\0') : 0 )
{
pConditionElx->m_nnumber = number;
pCondition = 0;
}
else // maybe elx, maybe named
{
pConditionElx->m_nnumber = -1;
m_namedconditionlist.Push(pConditionElx);
}
MoveNext(); // skip ')'
}
// alternative
{
int newflags = flags;
pConditionElx->m_pelxyes = BuildList(newflags);
}
if(curr.ch == RCHART('|'))
{
MoveNext(); // skip '|'
pConditionElx->m_pelxno = BuildAlternative(flags);
}
else
{
pConditionElx->m_pelxno = 0;
}
pElx = pConditionElx;
}
break;
default:
while(curr.ch != RCHART(0) && isspace(curr.ch)) Mov
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -