Files
2026-06-04 11:42:34 +02:00

1520 lines
34 KiB
C#

using System;
using System.Collections;
using System.Globalization;
namespace System.Text.RegularExpressions.Syntax
{
// Token: 0x020002D5 RID: 725
internal class Parser
{
// Token: 0x06001A61 RID: 6753 RVA: 0x0005F7D0 File Offset: 0x0005D9D0
public Parser()
{
this.caps = new ArrayList();
this.refs = new Hashtable();
}
// Token: 0x06001A62 RID: 6754 RVA: 0x0005F7F0 File Offset: 0x0005D9F0
public static int ParseDecimal(string str, ref int ptr)
{
return Parser.ParseNumber(str, ref ptr, 10, 1, int.MaxValue);
}
// Token: 0x06001A63 RID: 6755 RVA: 0x0005F804 File Offset: 0x0005DA04
public static int ParseOctal(string str, ref int ptr)
{
return Parser.ParseNumber(str, ref ptr, 8, 1, 3);
}
// Token: 0x06001A64 RID: 6756 RVA: 0x0005F810 File Offset: 0x0005DA10
public static int ParseHex(string str, ref int ptr, int digits)
{
return Parser.ParseNumber(str, ref ptr, 16, digits, digits);
}
// Token: 0x06001A65 RID: 6757 RVA: 0x0005F820 File Offset: 0x0005DA20
public static int ParseNumber(string str, ref int ptr, int b, int min, int max)
{
int num = ptr;
int num2 = 0;
int num3 = 0;
if (max < min)
{
max = int.MaxValue;
}
while (num3 < max && num < str.Length)
{
int num4 = Parser.ParseDigit(str[num++], b, num3);
if (num4 < 0)
{
num--;
break;
}
num2 = num2 * b + num4;
num3++;
}
if (num3 < min)
{
return -1;
}
ptr = num;
return num2;
}
// Token: 0x06001A66 RID: 6758 RVA: 0x0005F898 File Offset: 0x0005DA98
public static string ParseName(string str, ref int ptr)
{
if (char.IsDigit(str[ptr]))
{
int num = Parser.ParseNumber(str, ref ptr, 10, 1, 0);
if (num > 0)
{
return num.ToString();
}
return null;
}
else
{
int num2 = ptr;
while (Parser.IsNameChar(str[ptr]))
{
ptr++;
}
if (ptr - num2 > 0)
{
return str.Substring(num2, ptr - num2);
}
return null;
}
}
// Token: 0x06001A67 RID: 6759 RVA: 0x0005F918 File Offset: 0x0005DB18
public static string Escape(string str)
{
string text = string.Empty;
int i = 0;
while (i < str.Length)
{
char c = str[i];
char c2 = c;
switch (c2)
{
case ' ':
case '#':
case '$':
case '(':
case ')':
case '*':
case '+':
case '.':
goto IL_AF;
default:
switch (c2)
{
case '\t':
text += "\\t";
break;
case '\n':
text += "\\n";
break;
default:
switch (c2)
{
case '[':
case '\\':
case '^':
goto IL_AF;
default:
if (c2 == '{' || c2 == '|' || c2 == '?')
{
goto IL_AF;
}
text += c;
break;
}
break;
case '\f':
text += "\\f";
break;
case '\r':
text += "\\r";
break;
}
break;
}
IL_11C:
i++;
continue;
IL_AF:
text = text + "\\" + c;
goto IL_11C;
}
return text;
}
// Token: 0x06001A68 RID: 6760 RVA: 0x0005FA54 File Offset: 0x0005DC54
public static string Unescape(string str)
{
if (str.IndexOf('\\') == -1)
{
return str;
}
return new Parser().ParseString(str);
}
// Token: 0x06001A69 RID: 6761 RVA: 0x0005FA74 File Offset: 0x0005DC74
public RegularExpression ParseRegularExpression(string pattern, RegexOptions options)
{
this.pattern = pattern;
this.ptr = 0;
this.caps.Clear();
this.refs.Clear();
this.num_groups = 0;
RegularExpression regularExpression2;
try
{
RegularExpression regularExpression = new RegularExpression();
this.ParseGroup(regularExpression, options, null);
this.ResolveReferences();
regularExpression.GroupCount = this.num_groups;
regularExpression2 = regularExpression;
}
catch (IndexOutOfRangeException)
{
throw this.NewParseException("Unexpected end of pattern.");
}
return regularExpression2;
}
// Token: 0x06001A6A RID: 6762 RVA: 0x0005FB08 File Offset: 0x0005DD08
public int GetMapping(Hashtable mapping)
{
int count = this.caps.Count;
mapping.Add("0", 0);
for (int i = 0; i < count; i++)
{
CapturingGroup capturingGroup = (CapturingGroup)this.caps[i];
string text = ((capturingGroup.Name == null) ? capturingGroup.Index.ToString() : capturingGroup.Name);
if (mapping.Contains(text))
{
if ((int)mapping[text] != capturingGroup.Index)
{
throw new SystemException("invalid state");
}
}
else
{
mapping.Add(text, capturingGroup.Index);
}
}
return this.gap;
}
// Token: 0x06001A6B RID: 6763 RVA: 0x0005FBC8 File Offset: 0x0005DDC8
private void ParseGroup(Group group, RegexOptions options, Assertion assertion)
{
bool flag = group is RegularExpression;
Alternation alternation = null;
string text = null;
Group group2 = new Group();
Expression expression = null;
bool flag2 = false;
do
{
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
if (this.ptr >= this.pattern.Length)
{
break;
}
char c = this.pattern[this.ptr++];
char c2 = c;
switch (c2)
{
case '$':
{
Position position = ((!Parser.IsMultiline(options)) ? Position.End : Position.EndOfLine);
expression = new PositionAssertion(position);
break;
}
default:
switch (c2)
{
case '[':
expression = this.ParseCharacterClass(options);
break;
case '\\':
{
int num = this.ParseEscape();
if (num >= 0)
{
c = (char)num;
}
else
{
expression = this.ParseSpecial(options);
if (expression == null)
{
c = this.pattern[this.ptr++];
}
}
break;
}
default:
if (c2 == '?')
{
goto IL_25F;
}
if (c2 == '|')
{
if (text != null)
{
group2.AppendExpression(new Literal(text, Parser.IsIgnoreCase(options)));
text = null;
}
if (assertion != null)
{
if (assertion.TrueExpression == null)
{
assertion.TrueExpression = group2;
}
else
{
if (assertion.FalseExpression != null)
{
goto IL_230;
}
assertion.FalseExpression = group2;
}
}
else
{
if (alternation == null)
{
alternation = new Alternation();
}
alternation.AddAlternative(group2);
}
group2 = new Group();
continue;
}
break;
case '^':
{
Position position2 = ((!Parser.IsMultiline(options)) ? Position.Start : Position.StartOfLine);
expression = new PositionAssertion(position2);
break;
}
}
break;
case '(':
{
bool flag3 = Parser.IsIgnoreCase(options);
expression = this.ParseGroupingConstruct(ref options);
if (expression == null)
{
if (text != null && Parser.IsIgnoreCase(options) != flag3)
{
group2.AppendExpression(new Literal(text, Parser.IsIgnoreCase(options)));
text = null;
}
continue;
}
break;
}
case ')':
goto IL_1DA;
case '*':
case '+':
goto IL_25F;
case '.':
{
Category category = ((!Parser.IsSingleline(options)) ? Category.Any : Category.AnySingleline);
expression = new CharacterClass(category, false);
break;
}
}
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
if (this.ptr < this.pattern.Length)
{
char c3 = this.pattern[this.ptr];
int num2 = 0;
int num3 = 0;
bool flag4 = false;
bool flag5 = false;
if (c3 == '?' || c3 == '*' || c3 == '+')
{
this.ptr++;
flag5 = true;
c2 = c3;
if (c2 != '*')
{
if (c2 != '+')
{
if (c2 == '?')
{
num2 = 0;
num3 = 1;
}
}
else
{
num2 = 1;
num3 = int.MaxValue;
}
}
else
{
num2 = 0;
num3 = int.MaxValue;
}
}
else if (c3 == '{' && this.ptr + 1 < this.pattern.Length)
{
int num4 = this.ptr;
this.ptr++;
flag5 = this.ParseRepetitionBounds(out num2, out num3, options);
if (!flag5)
{
this.ptr = num4;
}
}
if (flag5)
{
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
if (this.ptr < this.pattern.Length && this.pattern[this.ptr] == '?')
{
this.ptr++;
flag4 = true;
}
Repetition repetition = new Repetition(num2, num3, flag4);
if (expression == null)
{
repetition.Expression = new Literal(c.ToString(), Parser.IsIgnoreCase(options));
}
else
{
repetition.Expression = expression;
}
expression = repetition;
}
}
if (expression == null)
{
if (text == null)
{
text = string.Empty;
}
text += c;
}
else
{
if (text != null)
{
group2.AppendExpression(new Literal(text, Parser.IsIgnoreCase(options)));
text = null;
}
group2.AppendExpression(expression);
expression = null;
}
}
while (!flag || this.ptr < this.pattern.Length);
goto IL_484;
IL_1DA:
flag2 = true;
goto IL_484;
IL_230:
throw this.NewParseException("Too many | in (?()|).");
IL_25F:
throw this.NewParseException("Bad quantifier.");
IL_484:
if (flag && flag2)
{
throw this.NewParseException("Too many )'s.");
}
if (!flag && !flag2)
{
throw this.NewParseException("Not enough )'s.");
}
if (text != null)
{
group2.AppendExpression(new Literal(text, Parser.IsIgnoreCase(options)));
}
if (assertion != null)
{
if (assertion.TrueExpression == null)
{
assertion.TrueExpression = group2;
}
else
{
assertion.FalseExpression = group2;
}
group.AppendExpression(assertion);
}
else if (alternation != null)
{
alternation.AddAlternative(group2);
group.AppendExpression(alternation);
}
else
{
group.AppendExpression(group2);
}
}
// Token: 0x06001A6C RID: 6764 RVA: 0x000600F4 File Offset: 0x0005E2F4
private Expression ParseGroupingConstruct(ref RegexOptions options)
{
if (this.pattern[this.ptr] != '?')
{
Group group;
if (Parser.IsExplicitCapture(options))
{
group = new Group();
}
else
{
group = new CapturingGroup();
this.caps.Add(group);
}
this.ParseGroup(group, options, null);
return group;
}
this.ptr++;
char c = this.pattern[this.ptr];
switch (c)
{
case '!':
break;
default:
{
switch (c)
{
case 'i':
case 'm':
case 'n':
break;
default:
switch (c)
{
case ':':
{
this.ptr++;
Group group2 = new Group();
this.ParseGroup(group2, options, null);
return group2;
}
default:
if (c != '-' && c != 's' && c != 'x')
{
throw this.NewParseException("Bad grouping construct.");
}
break;
case '<':
case '=':
goto IL_1E5;
case '>':
{
this.ptr++;
Group group3 = new NonBacktrackingGroup();
this.ParseGroup(group3, options, null);
return group3;
}
}
break;
}
RegexOptions regexOptions = options;
this.ParseOptions(ref regexOptions, false);
if (this.pattern[this.ptr] == '-')
{
this.ptr++;
this.ParseOptions(ref regexOptions, true);
}
if (this.pattern[this.ptr] == ':')
{
this.ptr++;
Group group4 = new Group();
this.ParseGroup(group4, regexOptions, null);
return group4;
}
if (this.pattern[this.ptr] == ')')
{
this.ptr++;
options = regexOptions;
return null;
}
throw this.NewParseException("Bad options");
}
case '#':
this.ptr++;
while (this.pattern[this.ptr++] != ')')
{
if (this.ptr >= this.pattern.Length)
{
throw this.NewParseException("Unterminated (?#...) comment.");
}
}
return null;
case '\'':
goto IL_21C;
case '(':
{
this.ptr++;
int num = this.ptr;
string text = this.ParseName();
Assertion assertion;
if (text == null || this.pattern[this.ptr] != ')')
{
this.ptr = num;
ExpressionAssertion expressionAssertion = new ExpressionAssertion();
if (this.pattern[this.ptr] == '?')
{
this.ptr++;
if (!this.ParseAssertionType(expressionAssertion))
{
throw this.NewParseException("Bad conditional.");
}
}
else
{
expressionAssertion.Negate = false;
expressionAssertion.Reverse = false;
}
Group group5 = new Group();
this.ParseGroup(group5, options, null);
expressionAssertion.TestExpression = group5;
assertion = expressionAssertion;
}
else
{
this.ptr++;
assertion = new CaptureAssertion(new Literal(text, Parser.IsIgnoreCase(options)));
this.refs.Add(assertion, text);
}
Group group6 = new Group();
this.ParseGroup(group6, options, assertion);
return group6;
}
}
IL_1E5:
ExpressionAssertion expressionAssertion2 = new ExpressionAssertion();
if (this.ParseAssertionType(expressionAssertion2))
{
Group group7 = new Group();
this.ParseGroup(group7, options, null);
expressionAssertion2.TestExpression = group7;
return expressionAssertion2;
}
IL_21C:
char c2;
if (this.pattern[this.ptr] == '<')
{
c2 = '>';
}
else
{
c2 = '\'';
}
this.ptr++;
string text2 = this.ParseName();
if (this.pattern[this.ptr] == c2)
{
if (text2 == null)
{
throw this.NewParseException("Bad group name.");
}
this.ptr++;
CapturingGroup capturingGroup = new CapturingGroup();
capturingGroup.Name = text2;
this.caps.Add(capturingGroup);
this.ParseGroup(capturingGroup, options, null);
return capturingGroup;
}
else
{
if (this.pattern[this.ptr] != '-')
{
throw this.NewParseException("Bad group name.");
}
this.ptr++;
string text3 = this.ParseName();
if (text3 == null || this.pattern[this.ptr] != c2)
{
throw this.NewParseException("Bad balancing group name.");
}
this.ptr++;
BalancingGroup balancingGroup = new BalancingGroup();
balancingGroup.Name = text2;
if (balancingGroup.IsNamed)
{
this.caps.Add(balancingGroup);
}
this.refs.Add(balancingGroup, text3);
this.ParseGroup(balancingGroup, options, null);
return balancingGroup;
}
}
// Token: 0x06001A6D RID: 6765 RVA: 0x000605EC File Offset: 0x0005E7EC
private bool ParseAssertionType(ExpressionAssertion assertion)
{
if (this.pattern[this.ptr] == '<')
{
char c = this.pattern[this.ptr + 1];
if (c != '!')
{
if (c != '=')
{
return false;
}
assertion.Negate = false;
}
else
{
assertion.Negate = true;
}
assertion.Reverse = true;
this.ptr += 2;
}
else
{
char c = this.pattern[this.ptr];
if (c != '!')
{
if (c != '=')
{
return false;
}
assertion.Negate = false;
}
else
{
assertion.Negate = true;
}
assertion.Reverse = false;
this.ptr++;
}
return true;
}
// Token: 0x06001A6E RID: 6766 RVA: 0x000606C8 File Offset: 0x0005E8C8
private void ParseOptions(ref RegexOptions options, bool negate)
{
for (;;)
{
char c = this.pattern[this.ptr];
switch (c)
{
case 'i':
if (negate)
{
options &= ~RegexOptions.IgnoreCase;
}
else
{
options |= RegexOptions.IgnoreCase;
}
break;
default:
if (c != 's')
{
if (c != 'x')
{
return;
}
if (negate)
{
options &= ~RegexOptions.IgnorePatternWhitespace;
}
else
{
options |= RegexOptions.IgnorePatternWhitespace;
}
}
else if (negate)
{
options &= ~RegexOptions.Singleline;
}
else
{
options |= RegexOptions.Singleline;
}
break;
case 'm':
if (negate)
{
options &= ~RegexOptions.Multiline;
}
else
{
options |= RegexOptions.Multiline;
}
break;
case 'n':
if (negate)
{
options &= ~RegexOptions.ExplicitCapture;
}
else
{
options |= RegexOptions.ExplicitCapture;
}
break;
}
this.ptr++;
}
}
// Token: 0x06001A6F RID: 6767 RVA: 0x000607C8 File Offset: 0x0005E9C8
private Expression ParseCharacterClass(RegexOptions options)
{
bool flag = false;
if (this.pattern[this.ptr] == '^')
{
flag = true;
this.ptr++;
}
bool flag2 = Parser.IsECMAScript(options);
CharacterClass characterClass = new CharacterClass(flag, Parser.IsIgnoreCase(options));
if (this.pattern[this.ptr] == ']')
{
characterClass.AddCharacter(']');
this.ptr++;
}
int num = -1;
bool flag3 = false;
bool flag4 = false;
while (this.ptr < this.pattern.Length)
{
int num2 = (int)this.pattern[this.ptr++];
if (num2 == 93)
{
flag4 = true;
break;
}
if (num2 == 45 && num >= 0 && !flag3)
{
flag3 = true;
}
else
{
if (num2 == 92)
{
num2 = this.ParseEscape();
if (num2 < 0)
{
num2 = (int)this.pattern[this.ptr++];
int num3 = num2;
switch (num3)
{
case 80:
goto IL_1D1;
default:
switch (num3)
{
case 112:
goto IL_1D1;
default:
switch (num3)
{
case 98:
num2 = 8;
goto IL_212;
default:
if (num3 != 68)
{
if (num3 != 87 && num3 != 119)
{
goto IL_212;
}
characterClass.AddCategory((!flag2) ? Category.Word : Category.EcmaWord, num2 == 87);
goto IL_1EC;
}
break;
case 100:
break;
}
characterClass.AddCategory((!flag2) ? Category.Digit : Category.EcmaDigit, num2 == 68);
break;
case 115:
goto IL_1B3;
}
break;
case 83:
goto IL_1B3;
}
IL_1EC:
if (flag3)
{
throw this.NewParseException("character range cannot have category \\" + num2);
}
num = -1;
continue;
IL_1B3:
characterClass.AddCategory((!flag2) ? Category.WhiteSpace : Category.EcmaWhiteSpace, num2 == 83);
goto IL_1EC;
IL_1D1:
characterClass.AddCategory(this.ParseUnicodeCategory(), num2 == 80);
goto IL_1EC;
}
}
IL_212:
if (flag3)
{
if (num2 < num)
{
throw this.NewParseException(string.Concat(new object[] { "[", num, "-", num2, "] range in reverse order." }));
}
characterClass.AddRange((char)num, (char)num2);
num = -1;
flag3 = false;
}
else
{
characterClass.AddCharacter((char)num2);
num = num2;
}
}
}
if (!flag4)
{
throw this.NewParseException("Unterminated [] set.");
}
if (flag3)
{
characterClass.AddCharacter('-');
}
return characterClass;
}
// Token: 0x06001A70 RID: 6768 RVA: 0x00060A90 File Offset: 0x0005EC90
private bool ParseRepetitionBounds(out int min, out int max, RegexOptions options)
{
min = (max = 0);
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
int num;
if (this.pattern[this.ptr] == ',')
{
num = -1;
}
else
{
num = this.ParseNumber(10, 1, 0);
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
}
char c = this.pattern[this.ptr++];
int num2;
if (c != ',')
{
if (c != '}')
{
return false;
}
num2 = num;
}
else
{
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
num2 = this.ParseNumber(10, 1, 0);
this.ConsumeWhitespace(Parser.IsIgnorePatternWhitespace(options));
if (this.pattern[this.ptr++] != '}')
{
return false;
}
}
if (num > 2147483647 || num2 > 2147483647)
{
throw this.NewParseException("Illegal {x, y} - maximum of 2147483647.");
}
if (num2 >= 0 && num2 < num)
{
throw this.NewParseException("Illegal {x, y} with x > y.");
}
min = num;
if (num2 > 0)
{
max = num2;
}
else
{
max = int.MaxValue;
}
return true;
}
// Token: 0x06001A71 RID: 6769 RVA: 0x00060BC8 File Offset: 0x0005EDC8
private Category ParseUnicodeCategory()
{
if (this.pattern[this.ptr++] != '{')
{
throw this.NewParseException("Incomplete \\p{X} character escape.");
}
string text = Parser.ParseName(this.pattern, ref this.ptr);
if (text == null)
{
throw this.NewParseException("Incomplete \\p{X} character escape.");
}
Category category = CategoryUtils.CategoryFromName(text);
if (category == Category.None)
{
throw this.NewParseException("Unknown property '" + text + "'.");
}
if (this.pattern[this.ptr++] != '}')
{
throw this.NewParseException("Incomplete \\p{X} character escape.");
}
return category;
}
// Token: 0x06001A72 RID: 6770 RVA: 0x00060C7C File Offset: 0x0005EE7C
private Expression ParseSpecial(RegexOptions options)
{
int num = this.ptr;
bool flag = Parser.IsECMAScript(options);
char c = this.pattern[this.ptr++];
Expression expression;
switch (c)
{
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
this.ptr--;
int num2 = this.ParseNumber(10, 1, 0);
if (num2 < 0)
{
this.ptr = num;
return null;
}
Reference reference = new BackslashNumber(Parser.IsIgnoreCase(options), flag);
this.refs.Add(reference, num2.ToString());
expression = reference;
break;
}
default:
switch (c)
{
case 'P':
expression = new CharacterClass(this.ParseUnicodeCategory(), true);
break;
default:
switch (c)
{
case 'W':
expression = new CharacterClass((!flag) ? Category.Word : Category.EcmaWord, true);
break;
default:
switch (c)
{
case 'p':
expression = new CharacterClass(this.ParseUnicodeCategory(), false);
break;
default:
switch (c)
{
case 'w':
expression = new CharacterClass((!flag) ? Category.Word : Category.EcmaWord, false);
break;
default:
switch (c)
{
case 'b':
expression = new PositionAssertion(Position.Boundary);
break;
default:
if (c != 'k')
{
expression = null;
}
else
{
char c2 = this.pattern[this.ptr++];
if (c2 == '<')
{
c2 = '>';
}
else if (c2 != '\'')
{
throw this.NewParseException("Malformed \\k<...> named backreference.");
}
string text = this.ParseName();
if (text == null || this.pattern[this.ptr] != c2)
{
throw this.NewParseException("Malformed \\k<...> named backreference.");
}
this.ptr++;
Reference reference2 = new Reference(Parser.IsIgnoreCase(options));
this.refs.Add(reference2, text);
expression = reference2;
}
break;
case 'd':
expression = new CharacterClass((!flag) ? Category.Digit : Category.EcmaDigit, false);
break;
}
break;
case 'z':
expression = new PositionAssertion(Position.EndOfString);
break;
}
break;
case 's':
expression = new CharacterClass((!flag) ? Category.WhiteSpace : Category.EcmaWhiteSpace, false);
break;
}
break;
case 'Z':
expression = new PositionAssertion(Position.End);
break;
}
break;
case 'S':
expression = new CharacterClass((!flag) ? Category.WhiteSpace : Category.EcmaWhiteSpace, true);
break;
}
break;
case 'A':
expression = new PositionAssertion(Position.StartOfString);
break;
case 'B':
expression = new PositionAssertion(Position.NonBoundary);
break;
case 'D':
expression = new CharacterClass((!flag) ? Category.Digit : Category.EcmaDigit, true);
break;
case 'G':
expression = new PositionAssertion(Position.StartOfScan);
break;
}
if (expression == null)
{
this.ptr = num;
}
return expression;
}
// Token: 0x06001A73 RID: 6771 RVA: 0x00060FC8 File Offset: 0x0005F1C8
private int ParseEscape()
{
int num = this.ptr;
if (num >= this.pattern.Length)
{
throw new ArgumentException(string.Format("Parsing \"{0}\" - Illegal \\ at end of pattern.", this.pattern), this.pattern);
}
char c = this.pattern[this.ptr++];
switch (c)
{
case 'n':
return 10;
default:
switch (c)
{
case 'a':
return 7;
default:
if (c != '0')
{
if (c != '\\')
{
this.ptr = num;
return -1;
}
return 92;
}
else
{
this.ptr--;
int num2 = this.ptr;
int num3 = Parser.ParseOctal(this.pattern, ref this.ptr);
if (num3 == -1 && num2 == this.ptr)
{
return 0;
}
return num3;
}
break;
case 'c':
{
int num4 = (int)this.pattern[this.ptr++];
if (num4 >= 64 && num4 <= 95)
{
return num4 - 64;
}
throw this.NewParseException("Unrecognized control character.");
}
case 'e':
return 27;
case 'f':
return 12;
}
break;
case 'r':
return 13;
case 't':
return 9;
case 'u':
{
int num4 = Parser.ParseHex(this.pattern, ref this.ptr, 4);
if (num4 < 0)
{
throw this.NewParseException("Insufficient hex digits");
}
return num4;
}
case 'v':
return 11;
case 'x':
{
int num4 = Parser.ParseHex(this.pattern, ref this.ptr, 2);
if (num4 < 0)
{
throw this.NewParseException("Insufficient hex digits");
}
return num4;
}
}
}
// Token: 0x06001A74 RID: 6772 RVA: 0x00061188 File Offset: 0x0005F388
private string ParseName()
{
return Parser.ParseName(this.pattern, ref this.ptr);
}
// Token: 0x06001A75 RID: 6773 RVA: 0x0006119C File Offset: 0x0005F39C
private static bool IsNameChar(char c)
{
UnicodeCategory unicodeCategory = char.GetUnicodeCategory(c);
return unicodeCategory != UnicodeCategory.ModifierLetter && (unicodeCategory == UnicodeCategory.ConnectorPunctuation || char.IsLetterOrDigit(c));
}
// Token: 0x06001A76 RID: 6774 RVA: 0x000611CC File Offset: 0x0005F3CC
private int ParseNumber(int b, int min, int max)
{
return Parser.ParseNumber(this.pattern, ref this.ptr, b, min, max);
}
// Token: 0x06001A77 RID: 6775 RVA: 0x000611E4 File Offset: 0x0005F3E4
private static int ParseDigit(char c, int b, int n)
{
switch (b)
{
case 8:
if (c >= '0' && c <= '7')
{
return (int)(c - '0');
}
return -1;
default:
if (b != 16)
{
return -1;
}
if (c >= '0' && c <= '9')
{
return (int)(c - '0');
}
if (c >= 'a' && c <= 'f')
{
return (int)('\n' + c - 'a');
}
if (c >= 'A' && c <= 'F')
{
return (int)('\n' + c - 'A');
}
return -1;
case 10:
if (c >= '0' && c <= '9')
{
return (int)(c - '0');
}
return -1;
}
}
// Token: 0x06001A78 RID: 6776 RVA: 0x0006128C File Offset: 0x0005F48C
private void ConsumeWhitespace(bool ignore)
{
while (this.ptr < this.pattern.Length)
{
if (this.pattern[this.ptr] == '(')
{
if (this.ptr + 3 >= this.pattern.Length)
{
return;
}
if (this.pattern[this.ptr + 1] != '?' || this.pattern[this.ptr + 2] != '#')
{
return;
}
this.ptr += 3;
while (this.ptr < this.pattern.Length && this.pattern[this.ptr++] != ')')
{
}
}
else if (ignore && this.pattern[this.ptr] == '#')
{
while (this.ptr < this.pattern.Length && this.pattern[this.ptr++] != '\n')
{
}
}
else
{
if (!ignore || !char.IsWhiteSpace(this.pattern[this.ptr]))
{
return;
}
while (this.ptr < this.pattern.Length && char.IsWhiteSpace(this.pattern[this.ptr]))
{
this.ptr++;
}
}
}
}
// Token: 0x06001A79 RID: 6777 RVA: 0x00061438 File Offset: 0x0005F638
private string ParseString(string pattern)
{
this.pattern = pattern;
this.ptr = 0;
StringBuilder stringBuilder = new StringBuilder(pattern.Length);
while (this.ptr < pattern.Length)
{
int num = (int)pattern[this.ptr++];
if (num == 92)
{
num = this.ParseEscape();
if (num < 0)
{
num = (int)pattern[this.ptr++];
if (num == 98)
{
num = 8;
}
}
}
stringBuilder.Append((char)num);
}
return stringBuilder.ToString();
}
// Token: 0x06001A7A RID: 6778 RVA: 0x000614D4 File Offset: 0x0005F6D4
private void ResolveReferences()
{
int num = 1;
Hashtable hashtable = new Hashtable();
ArrayList arrayList = null;
foreach (object obj in this.caps)
{
CapturingGroup capturingGroup = (CapturingGroup)obj;
if (capturingGroup.Name == null)
{
hashtable.Add(num.ToString(), capturingGroup);
capturingGroup.Index = num++;
this.num_groups++;
}
}
foreach (object obj2 in this.caps)
{
CapturingGroup capturingGroup2 = (CapturingGroup)obj2;
if (capturingGroup2.Name != null)
{
if (hashtable.Contains(capturingGroup2.Name))
{
CapturingGroup capturingGroup3 = (CapturingGroup)hashtable[capturingGroup2.Name];
capturingGroup2.Index = capturingGroup3.Index;
if (capturingGroup2.Index == num)
{
num++;
}
else if (capturingGroup2.Index > num)
{
arrayList.Add(capturingGroup2);
}
}
else
{
if (char.IsDigit(capturingGroup2.Name[0]))
{
int num2 = 0;
int num3 = Parser.ParseDecimal(capturingGroup2.Name, ref num2);
if (num2 == capturingGroup2.Name.Length)
{
capturingGroup2.Index = num3;
hashtable.Add(capturingGroup2.Name, capturingGroup2);
this.num_groups++;
if (num3 == num)
{
num++;
}
else
{
if (arrayList == null)
{
arrayList = new ArrayList(4);
}
arrayList.Add(capturingGroup2);
}
continue;
}
}
string text = num.ToString();
while (hashtable.Contains(text))
{
int num4;
num = (num4 = num + 1);
text = num4.ToString();
}
hashtable.Add(text, capturingGroup2);
hashtable.Add(capturingGroup2.Name, capturingGroup2);
capturingGroup2.Index = num++;
this.num_groups++;
}
}
}
this.gap = num;
if (arrayList != null)
{
this.HandleExplicitNumericGroups(arrayList);
}
foreach (object obj3 in this.refs.Keys)
{
Expression expression = (Expression)obj3;
string text2 = (string)this.refs[expression];
if (!hashtable.Contains(text2))
{
if (!(expression is CaptureAssertion) || char.IsDigit(text2[0]))
{
BackslashNumber backslashNumber = expression as BackslashNumber;
if (backslashNumber == null || !backslashNumber.ResolveReference(text2, hashtable))
{
throw this.NewParseException("Reference to undefined group " + ((!char.IsDigit(text2[0])) ? "name " : "number ") + text2);
}
}
}
else
{
CapturingGroup capturingGroup4 = (CapturingGroup)hashtable[text2];
if (expression is Reference)
{
((Reference)expression).CapturingGroup = capturingGroup4;
}
else if (expression is CaptureAssertion)
{
((CaptureAssertion)expression).CapturingGroup = capturingGroup4;
}
else if (expression is BalancingGroup)
{
((BalancingGroup)expression).Balance = capturingGroup4;
}
}
}
}
// Token: 0x06001A7B RID: 6779 RVA: 0x000618C4 File Offset: 0x0005FAC4
private void HandleExplicitNumericGroups(ArrayList explicit_numeric_groups)
{
int num = this.gap;
int i = 0;
int count = explicit_numeric_groups.Count;
explicit_numeric_groups.Sort();
while (i < count)
{
CapturingGroup capturingGroup = (CapturingGroup)explicit_numeric_groups[i];
if (capturingGroup.Index > num)
{
break;
}
if (capturingGroup.Index == num)
{
num++;
}
i++;
}
this.gap = num;
int num2 = num;
while (i < count)
{
CapturingGroup capturingGroup2 = (CapturingGroup)explicit_numeric_groups[i];
if (capturingGroup2.Index == num2)
{
capturingGroup2.Index = num - 1;
}
else
{
num2 = capturingGroup2.Index;
capturingGroup2.Index = num++;
}
i++;
}
}
// Token: 0x06001A7C RID: 6780 RVA: 0x00061980 File Offset: 0x0005FB80
private static bool IsIgnoreCase(RegexOptions options)
{
return (options & RegexOptions.IgnoreCase) != RegexOptions.None;
}
// Token: 0x06001A7D RID: 6781 RVA: 0x0006198C File Offset: 0x0005FB8C
private static bool IsMultiline(RegexOptions options)
{
return (options & RegexOptions.Multiline) != RegexOptions.None;
}
// Token: 0x06001A7E RID: 6782 RVA: 0x00061998 File Offset: 0x0005FB98
private static bool IsExplicitCapture(RegexOptions options)
{
return (options & RegexOptions.ExplicitCapture) != RegexOptions.None;
}
// Token: 0x06001A7F RID: 6783 RVA: 0x000619A4 File Offset: 0x0005FBA4
private static bool IsSingleline(RegexOptions options)
{
return (options & RegexOptions.Singleline) != RegexOptions.None;
}
// Token: 0x06001A80 RID: 6784 RVA: 0x000619B0 File Offset: 0x0005FBB0
private static bool IsIgnorePatternWhitespace(RegexOptions options)
{
return (options & RegexOptions.IgnorePatternWhitespace) != RegexOptions.None;
}
// Token: 0x06001A81 RID: 6785 RVA: 0x000619BC File Offset: 0x0005FBBC
private static bool IsECMAScript(RegexOptions options)
{
return (options & RegexOptions.ECMAScript) != RegexOptions.None;
}
// Token: 0x06001A82 RID: 6786 RVA: 0x000619CC File Offset: 0x0005FBCC
private ArgumentException NewParseException(string msg)
{
msg = "parsing \"" + this.pattern + "\" - " + msg;
return new ArgumentException(msg, this.pattern);
}
// Token: 0x0400159F RID: 5535
private string pattern;
// Token: 0x040015A0 RID: 5536
private int ptr;
// Token: 0x040015A1 RID: 5537
private ArrayList caps;
// Token: 0x040015A2 RID: 5538
private Hashtable refs;
// Token: 0x040015A3 RID: 5539
private int num_groups;
// Token: 0x040015A4 RID: 5540
private int gap;
}
}