private void ParseGroup() {
Debug.Assert(_rubyPattern[_index - 1] == '(');
if (Read('?')) {
int c = Read();
if (c == '#') {
while (true) {
c = Read();
if (c == -1) {
throw MakeError("end pattern in group");
}
if (c == ')') {
break;
}
}
return;
}
Append('(');
Append('?');
switch (c) {
case '-':
case 'i':
case 'm':
case 'x':
while (true) {
if (c == 'm') {
// Map (?m) to (?s) ie. RegexOptions.SingleLine
Append('s');
} else if (c == 'i' || c == 'x' || c == '-') {
Append((char)c);
} else if (c == ':') {
Append(':');
break;
} else if (c == ')' || c == -1) {
Back();
break;
} else {
throw MakeError("undefined group option");
}
c = Read();
}
break;
case ':':
// non-captured group
Append(':');
break;
case '=':
// positive lookahead
Append('=');
break;
case '!':
// negative lookahead
Append('!');
break;
case '>':
// greedy subexpression
Append('>');
break;
case '<':
Append('<');
c = Read();
if (c == '=' || c == '!') {
// positive/negative lookbehind assertion
Append((char)c);
} else {
ParseGroupName(c, '>');
}
break;
case '\'':
Append('\'');
ParseGroupName(Read(), '\'');
break;
default:
throw MakeError("undefined group option");
}
} else {
Append('(');
}
Parse(true);
Append(')');
}