internal RegExTree CharClass()
{
// Assert chr == '['
// Need to build a new string taking into account char escapes
Leaf leaf = new Leaf(RegOp.charClass);
bool invert = false;
scan(); // read past '['
if (!esc && chr == '^')
{
invert = true;
scan(); // read past '^'
}
leaf.rangeLit = new RangeLiteral(invert);
// Special case of '-' at start, taken as ordinary class member.
// This is correct for LEX specification, but is undocumented
// behavior for FLEX. GPLEX gives a friendly warning, just in
// case this is actually a typographical error.
if (!esc && chr == '-')
{
Warn(113, index - 1, 1, "-");
leaf.rangeLit.list.Add(new CharRange('-'));
scan(); // read past -'
}
while (chr != NUL && (esc || chr != ']'))
{
int lhCodePoint;
int startIx = index-1; // save starting index for error reporting
lhCodePoint = (esc ? EscapedChar() : CodePoint());
if (!esc && lhCodePoint == (int)'-')
Error(82, startIx, index - startIx, null);
//
// There are three possible elements here:
// * a singleton character
// * a character range
// * a character category like [:IsLetter:]
//
if (chr == '[' && !esc && peek() == ':') // character category
{
Leaf rslt = GetCharCategory();
leaf.Merge(rslt);
}
else
{
scan();
if (!esc && chr == '-') // character range
{
scan();
if (!esc && chr == ']')
{
// Special case of '-' at end, taken as ordinary class member.
// This is correct for LEX specification, but is undocumented
// behavior for FLEX. GPLEX gives a friendly warning, just in
// case this is actually a typographical error.
leaf.rangeLit.list.Add(new CharRange(lhCodePoint));
leaf.rangeLit.list.Add(new CharRange('-'));
//Error(81, idx, index - idx - 1);
Warn(114, startIx, index - startIx - 1, String.Format(
CultureInfo.InvariantCulture,
"'{0}','{1}'",
CharacterUtilities.Map(lhCodePoint),
'-'));
}
else
{
int rhCodePoint = (esc ? EscapedChar() : CodePoint());
if (rhCodePoint < lhCodePoint)
Error(54, startIx, index - startIx, null);
scan();
leaf.rangeLit.list.Add(new CharRange(lhCodePoint, rhCodePoint));
}
}
else // character singleton
{
leaf.rangeLit.list.Add(new CharRange(lhCodePoint));
}
}
}
checkAndScan(']');
return leaf;
}