internal RegexNode ScanDollar()
{
if (CharsRight() == 0)
return new RegexNode(RegexNode.One, _options, '$');
char ch = RightChar();
bool angled;
int backpos = Textpos();
int lastEndPos = backpos;
// Note angle
if (ch == '{' && CharsRight() > 1)
{
angled = true;
MoveRight();
ch = RightChar();
}
else
{
angled = false;
}
// Try to parse backreference: \1 or \{1} or \{cap}
if (ch >= '0' && ch <= '9')
{
if (!angled && UseOptionE())
{
int capnum = -1;
int newcapnum = (int)(ch - '0');
MoveRight();
if (IsCaptureSlot(newcapnum))
{
capnum = newcapnum;
lastEndPos = Textpos();
}
while (CharsRight() > 0 && (ch = RightChar()) >= '0' && ch <= '9')
{
int digit = (int)(ch - '0');
if (newcapnum > (MaxValueDiv10) || (newcapnum == (MaxValueDiv10) && digit > (MaxValueMod10)))
throw MakeException(SR.CaptureGroupOutOfRange);
newcapnum = newcapnum * 10 + digit;
MoveRight();
if (IsCaptureSlot(newcapnum))
{
capnum = newcapnum;
lastEndPos = Textpos();
}
}
Textto(lastEndPos);
if (capnum >= 0)
return new RegexNode(RegexNode.Ref, _options, capnum);
}
else
{
int capnum = ScanDecimal();
if (!angled || CharsRight() > 0 && MoveRightGetChar() == '}')
{
if (IsCaptureSlot(capnum))
return new RegexNode(RegexNode.Ref, _options, capnum);
}
}
}
else if (angled && RegexCharClass.IsWordChar(ch))
{
string capname = ScanCapname();
if (CharsRight() > 0 && MoveRightGetChar() == '}')
{
if (IsCaptureName(capname))
return new RegexNode(RegexNode.Ref, _options, CaptureSlotFromName(capname));
}
}
else if (!angled)
{
int capnum = 1;
switch (ch)
{
case '$':
MoveRight();
return new RegexNode(RegexNode.One, _options, '$');
case '&':
capnum = 0;
break;
case '`':
capnum = RegexReplacement.LeftPortion;
break;
case '\'':
capnum = RegexReplacement.RightPortion;
break;
case '+':
capnum = RegexReplacement.LastGroup;
break;
case '_':
capnum = RegexReplacement.WholeString;
break;
}
if (capnum != 1)
{
MoveRight();
return new RegexNode(RegexNode.Ref, _options, capnum);
}
}
// unrecognized $: literalize
Textto(backpos);
return new RegexNode(RegexNode.One, _options, '$');
}