internal RegexNode ScanBasicBackslash()
{
if (CharsRight() == 0)
throw MakeException(SR.IllegalEndEscape);
char ch;
bool angled = false;
char close = '\0';
int backpos;
backpos = Textpos();
ch = RightChar();
// allow \k<foo> instead of \<foo>, which is now deprecated
if (ch == 'k')
{
if (CharsRight() >= 2)
{
MoveRight();
ch = MoveRightGetChar();
if (ch == '<' || ch == '\'')
{
angled = true;
close = (ch == '\'') ? '\'' : '>';
}
}
if (!angled || CharsRight() <= 0)
throw MakeException(SR.MalformedNameRef);
ch = RightChar();
}
// Note angle without \g
else if ((ch == '<' || ch == '\'') && CharsRight() > 1)
{
angled = true;
close = (ch == '\'') ? '\'' : '>';
MoveRight();
ch = RightChar();
}
// Try to parse backreference: \<1> or \<cap>
if (angled && ch >= '0' && ch <= '9')
{
int capnum = ScanDecimal();
if (CharsRight() > 0 && MoveRightGetChar() == close)
{
if (IsCaptureSlot(capnum))
return new RegexNode(RegexNode.Ref, _options, capnum);
else
throw MakeException(SR.Format(SR.UndefinedBackref, capnum.ToString(CultureInfo.CurrentCulture)));
}
}
// Try to parse backreference or octal: \1
else if (!angled && ch >= '1' && ch <= '9')
{
if (UseOptionE())
{
int capnum = -1;
int newcapnum = (int)(ch - '0');
int pos = Textpos() - 1;
while (newcapnum <= _captop)
{
if (IsCaptureSlot(newcapnum) && (_caps == null || (int)_caps[newcapnum] < pos))
capnum = newcapnum;
MoveRight();
if (CharsRight() == 0 || (ch = RightChar()) < '0' || ch > '9')
break;
newcapnum = newcapnum * 10 + (int)(ch - '0');
}
if (capnum >= 0)
return new RegexNode(RegexNode.Ref, _options, capnum);
}
else
{
int capnum = ScanDecimal();
if (IsCaptureSlot(capnum))
return new RegexNode(RegexNode.Ref, _options, capnum);
else if (capnum <= 9)
throw MakeException(SR.Format(SR.UndefinedBackref, capnum.ToString(CultureInfo.CurrentCulture)));
}
}
else if (angled && RegexCharClass.IsWordChar(ch))
{
string capname = ScanCapname();
if (CharsRight() > 0 && MoveRightGetChar() == close)
{
if (IsCaptureName(capname))
return new RegexNode(RegexNode.Ref, _options, CaptureSlotFromName(capname));
else
throw MakeException(SR.Format(SR.UndefinedNameRef, capname));
}
}
// Not backreference: must be char code
Textto(backpos);
ch = ScanCharEscape();
if (UseOptionI())
ch = _culture.TextInfo.ToLower(ch);
return new RegexNode(RegexNode.One, _options, ch);
}