1356 lines
30 KiB
C#
1356 lines
30 KiB
C#
using System;
|
|
|
|
namespace System.Text.RegularExpressions
|
|
{
|
|
// Token: 0x020002CE RID: 718
|
|
internal class Interpreter : BaseMachine
|
|
{
|
|
// Token: 0x06001A1A RID: 6682 RVA: 0x0005D280 File Offset: 0x0005B480
|
|
public Interpreter(ushort[] program)
|
|
{
|
|
this.program = program;
|
|
this.qs = null;
|
|
this.group_count = this.ReadProgramCount(1) + 1;
|
|
this.match_min = this.ReadProgramCount(3);
|
|
this.program_start = 7;
|
|
this.groups = new int[this.group_count];
|
|
}
|
|
|
|
// Token: 0x06001A1B RID: 6683 RVA: 0x0005D2E4 File Offset: 0x0005B4E4
|
|
private int ReadProgramCount(int ptr)
|
|
{
|
|
int num = (int)this.program[ptr + 1];
|
|
num <<= 16;
|
|
return num + (int)this.program[ptr];
|
|
}
|
|
|
|
// Token: 0x06001A1C RID: 6684 RVA: 0x0005D310 File Offset: 0x0005B510
|
|
public override Match Scan(Regex regex, string text, int start, int end)
|
|
{
|
|
this.text = text;
|
|
this.text_end = end;
|
|
this.scan_ptr = start;
|
|
if (this.Eval(Interpreter.Mode.Match, ref this.scan_ptr, this.program_start))
|
|
{
|
|
return this.GenerateMatch(regex);
|
|
}
|
|
return Match.Empty;
|
|
}
|
|
|
|
// Token: 0x06001A1D RID: 6685 RVA: 0x0005D350 File Offset: 0x0005B550
|
|
private void Reset()
|
|
{
|
|
this.ResetGroups();
|
|
this.fast = (this.repeat = null);
|
|
}
|
|
|
|
// Token: 0x06001A1E RID: 6686 RVA: 0x0005D374 File Offset: 0x0005B574
|
|
private bool Eval(Interpreter.Mode mode, ref int ref_ptr, int pc)
|
|
{
|
|
int num = ref_ptr;
|
|
Interpreter.RepeatContext repeatContext;
|
|
int start;
|
|
int count;
|
|
for (;;)
|
|
{
|
|
OpFlags opFlags;
|
|
for (;;)
|
|
{
|
|
ushort num2 = this.program[pc];
|
|
OpCode opCode = (OpCode)(num2 & 255);
|
|
opFlags = (OpFlags)(num2 & 65280);
|
|
switch (opCode)
|
|
{
|
|
case OpCode.False:
|
|
goto IL_4B8;
|
|
case OpCode.True:
|
|
goto IL_4BD;
|
|
case OpCode.Position:
|
|
if (!this.IsPosition((Position)this.program[pc + 1], num))
|
|
{
|
|
goto Block_44;
|
|
}
|
|
pc += 2;
|
|
break;
|
|
case OpCode.String:
|
|
{
|
|
bool flag = (ushort)(opFlags & OpFlags.RightToLeft) != 0;
|
|
bool flag2 = (ushort)(opFlags & OpFlags.IgnoreCase) != 0;
|
|
int num3 = (int)this.program[pc + 1];
|
|
if (flag)
|
|
{
|
|
num -= num3;
|
|
if (num < 0)
|
|
{
|
|
goto Block_46;
|
|
}
|
|
}
|
|
else if (num + num3 > this.text_end)
|
|
{
|
|
goto Block_47;
|
|
}
|
|
pc += 2;
|
|
for (int i = 0; i < num3; i++)
|
|
{
|
|
char c = this.text[num + i];
|
|
if (flag2)
|
|
{
|
|
c = char.ToLower(c);
|
|
}
|
|
if (c != (char)this.program[pc++])
|
|
{
|
|
goto Block_49;
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
num += num3;
|
|
}
|
|
break;
|
|
}
|
|
case OpCode.Reference:
|
|
{
|
|
bool flag3 = (ushort)(opFlags & OpFlags.RightToLeft) != 0;
|
|
bool flag4 = (ushort)(opFlags & OpFlags.IgnoreCase) != 0;
|
|
int lastDefined = this.GetLastDefined((int)this.program[pc + 1]);
|
|
if (lastDefined < 0)
|
|
{
|
|
goto Block_52;
|
|
}
|
|
int index = this.marks[lastDefined].Index;
|
|
int length = this.marks[lastDefined].Length;
|
|
if (flag3)
|
|
{
|
|
num -= length;
|
|
if (num < 0)
|
|
{
|
|
goto Block_54;
|
|
}
|
|
}
|
|
else if (num + length > this.text_end)
|
|
{
|
|
goto Block_55;
|
|
}
|
|
pc += 2;
|
|
if (flag4)
|
|
{
|
|
for (int j = 0; j < length; j++)
|
|
{
|
|
if (char.ToLower(this.text[num + j]) != char.ToLower(this.text[index + j]))
|
|
{
|
|
goto Block_57;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int k = 0; k < length; k++)
|
|
{
|
|
if (this.text[num + k] != this.text[index + k])
|
|
{
|
|
goto Block_59;
|
|
}
|
|
}
|
|
}
|
|
if (!flag3)
|
|
{
|
|
num += length;
|
|
}
|
|
break;
|
|
}
|
|
case OpCode.Character:
|
|
case OpCode.Category:
|
|
case OpCode.NotCategory:
|
|
case OpCode.Range:
|
|
case OpCode.Set:
|
|
if (!this.EvalChar(mode, ref num, ref pc, false))
|
|
{
|
|
goto Block_61;
|
|
}
|
|
break;
|
|
case OpCode.In:
|
|
{
|
|
int num4 = pc + (int)this.program[pc + 1];
|
|
pc += 2;
|
|
if (!this.EvalChar(mode, ref num, ref pc, true))
|
|
{
|
|
goto Block_62;
|
|
}
|
|
pc = num4;
|
|
break;
|
|
}
|
|
case OpCode.Open:
|
|
this.Open((int)this.program[pc + 1], num);
|
|
pc += 2;
|
|
break;
|
|
case OpCode.Close:
|
|
this.Close((int)this.program[pc + 1], num);
|
|
pc += 2;
|
|
break;
|
|
case OpCode.Balance:
|
|
goto IL_7DB;
|
|
case OpCode.BalanceStart:
|
|
{
|
|
int num5 = num;
|
|
if (!this.Eval(Interpreter.Mode.Match, ref num, pc + 5))
|
|
{
|
|
goto Block_63;
|
|
}
|
|
if (!this.Balance((int)this.program[pc + 1], (int)this.program[pc + 2], this.program[pc + 3] == 1, num5))
|
|
{
|
|
goto Block_65;
|
|
}
|
|
pc += (int)this.program[pc + 4];
|
|
break;
|
|
}
|
|
case OpCode.IfDefined:
|
|
{
|
|
int lastDefined2 = this.GetLastDefined((int)this.program[pc + 2]);
|
|
if (lastDefined2 < 0)
|
|
{
|
|
pc += (int)this.program[pc + 1];
|
|
}
|
|
else
|
|
{
|
|
pc += 3;
|
|
}
|
|
break;
|
|
}
|
|
case OpCode.Sub:
|
|
if (!this.Eval(Interpreter.Mode.Match, ref num, pc + 2))
|
|
{
|
|
goto Block_67;
|
|
}
|
|
pc += (int)this.program[pc + 1];
|
|
break;
|
|
case OpCode.Test:
|
|
{
|
|
int num6 = this.Checkpoint();
|
|
int num7 = num;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num7, pc + 3))
|
|
{
|
|
pc += (int)this.program[pc + 1];
|
|
}
|
|
else
|
|
{
|
|
this.Backtrack(num6);
|
|
pc += (int)this.program[pc + 2];
|
|
}
|
|
break;
|
|
}
|
|
case OpCode.Branch:
|
|
goto IL_88A;
|
|
case OpCode.Jump:
|
|
pc += (int)this.program[pc + 1];
|
|
break;
|
|
case OpCode.Repeat:
|
|
goto IL_8EE;
|
|
case OpCode.Until:
|
|
goto IL_957;
|
|
case OpCode.FastRepeat:
|
|
goto IL_C6F;
|
|
case OpCode.Anchor:
|
|
goto IL_96;
|
|
case OpCode.Info:
|
|
goto IL_FE9;
|
|
}
|
|
}
|
|
for (;;)
|
|
{
|
|
IL_88A:
|
|
int num8 = this.Checkpoint();
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc + 2))
|
|
{
|
|
break;
|
|
}
|
|
this.Backtrack(num8);
|
|
pc += (int)this.program[pc + 1];
|
|
if ((this.program[pc] & 255) == 0)
|
|
{
|
|
goto Block_70;
|
|
}
|
|
}
|
|
IL_FF3:
|
|
ref_ptr = num;
|
|
if (mode == Interpreter.Mode.Match)
|
|
{
|
|
return true;
|
|
}
|
|
if (mode != Interpreter.Mode.Count)
|
|
{
|
|
break;
|
|
}
|
|
this.fast.Count++;
|
|
if (this.fast.IsMaximum || (this.fast.IsLazy && this.fast.IsMinimum))
|
|
{
|
|
return true;
|
|
}
|
|
pc = this.fast.Expression;
|
|
continue;
|
|
IL_96:
|
|
int num9 = (int)this.program[pc + 1];
|
|
int num10 = (int)this.program[pc + 2];
|
|
bool flag5 = (ushort)(opFlags & OpFlags.RightToLeft) != 0;
|
|
int num11 = ((!flag5) ? (num + num10) : (num - num10));
|
|
int num12 = this.text_end - this.match_min + num10;
|
|
int num13 = 0;
|
|
OpCode opCode2 = (OpCode)(this.program[pc + 3] & 255);
|
|
if (opCode2 == OpCode.Position && num9 == 6)
|
|
{
|
|
switch (this.program[pc + 4])
|
|
{
|
|
case 2:
|
|
if (flag5 || num10 == 0)
|
|
{
|
|
if (flag5)
|
|
{
|
|
num = num10;
|
|
}
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
if (num11 == 0)
|
|
{
|
|
num = 0;
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
num11++;
|
|
}
|
|
while ((flag5 && num11 >= 0) || (!flag5 && num11 <= num12))
|
|
{
|
|
if (num11 == 0 || this.text[num11 - 1] == '\n')
|
|
{
|
|
if (flag5)
|
|
{
|
|
num = ((num11 != num12) ? (num11 + num10) : num11);
|
|
}
|
|
else
|
|
{
|
|
num = ((num11 != 0) ? (num11 - num10) : num11);
|
|
}
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
}
|
|
if (flag5)
|
|
{
|
|
num11--;
|
|
}
|
|
else
|
|
{
|
|
num11++;
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
if (num11 == this.scan_ptr)
|
|
{
|
|
num = ((!flag5) ? (this.scan_ptr - num10) : (this.scan_ptr + num10));
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
if (this.qs != null || (opCode2 == OpCode.String && num9 == (int)(6 + this.program[pc + 4])))
|
|
{
|
|
bool flag6 = (this.program[pc + 3] & 1024) != 0;
|
|
if (this.qs == null)
|
|
{
|
|
bool flag7 = (this.program[pc + 3] & 512) != 0;
|
|
string @string = this.GetString(pc + 3);
|
|
this.qs = new QuickSearch(@string, flag7, flag6);
|
|
}
|
|
while ((flag5 && num11 >= num13) || (!flag5 && num11 <= num12))
|
|
{
|
|
if (flag6)
|
|
{
|
|
num11 = this.qs.Search(this.text, num11, num13);
|
|
if (num11 != -1)
|
|
{
|
|
num11 += this.qs.Length;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
num11 = this.qs.Search(this.text, num11, num12);
|
|
}
|
|
if (num11 < 0)
|
|
{
|
|
break;
|
|
}
|
|
num = ((!flag6) ? (num11 - num10) : (num11 + num10));
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
if (flag6)
|
|
{
|
|
num11 -= 2;
|
|
}
|
|
else
|
|
{
|
|
num11++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (opCode2 == OpCode.True)
|
|
{
|
|
while ((flag5 && num11 >= num13) || (!flag5 && num11 <= num12))
|
|
{
|
|
num = num11;
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
if (flag5)
|
|
{
|
|
num11--;
|
|
}
|
|
else
|
|
{
|
|
num11++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
while ((flag5 && num11 >= num13) || (!flag5 && num11 <= num12))
|
|
{
|
|
num = num11;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc + 3))
|
|
{
|
|
num = ((!flag5) ? (num11 - num10) : (num11 + num10));
|
|
if (this.TryMatch(ref num, pc + num9))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
}
|
|
if (flag5)
|
|
{
|
|
num11--;
|
|
}
|
|
else
|
|
{
|
|
num11++;
|
|
}
|
|
}
|
|
break;
|
|
IL_4BD:
|
|
IL_7DB:
|
|
goto IL_FF3;
|
|
IL_8EE:
|
|
this.repeat = new Interpreter.RepeatContext(this.repeat, this.ReadProgramCount(pc + 2), this.ReadProgramCount(pc + 4), (ushort)(opFlags & OpFlags.Lazy) != 0, pc + 6);
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc + (int)this.program[pc + 1]))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
goto IL_941;
|
|
IL_957:
|
|
repeatContext = this.repeat;
|
|
if (this.deep == repeatContext)
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
start = repeatContext.Start;
|
|
count = repeatContext.Count;
|
|
while (!repeatContext.IsMinimum)
|
|
{
|
|
repeatContext.Count++;
|
|
repeatContext.Start = num;
|
|
this.deep = repeatContext;
|
|
if (!this.Eval(Interpreter.Mode.Match, ref num, repeatContext.Expression))
|
|
{
|
|
goto Block_73;
|
|
}
|
|
if (this.deep != repeatContext)
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
}
|
|
if (num == repeatContext.Start)
|
|
{
|
|
this.repeat = repeatContext.Previous;
|
|
this.deep = null;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc + 1))
|
|
{
|
|
goto IL_FF3;
|
|
}
|
|
goto IL_A28;
|
|
}
|
|
else
|
|
{
|
|
if (repeatContext.IsLazy)
|
|
{
|
|
for (;;)
|
|
{
|
|
this.repeat = repeatContext.Previous;
|
|
this.deep = null;
|
|
int num14 = this.Checkpoint();
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc + 1))
|
|
{
|
|
break;
|
|
}
|
|
this.Backtrack(num14);
|
|
this.repeat = repeatContext;
|
|
if (repeatContext.IsMaximum)
|
|
{
|
|
goto Block_80;
|
|
}
|
|
repeatContext.Count++;
|
|
repeatContext.Start = num;
|
|
this.deep = repeatContext;
|
|
if (!this.Eval(Interpreter.Mode.Match, ref num, repeatContext.Expression))
|
|
{
|
|
goto Block_81;
|
|
}
|
|
if (this.deep != repeatContext)
|
|
{
|
|
break;
|
|
}
|
|
if (num == repeatContext.Start)
|
|
{
|
|
goto Block_83;
|
|
}
|
|
}
|
|
goto IL_FF3;
|
|
}
|
|
int count2 = this.stack.Count;
|
|
while (!repeatContext.IsMaximum)
|
|
{
|
|
int num15 = this.Checkpoint();
|
|
int num16 = num;
|
|
int start2 = repeatContext.Start;
|
|
repeatContext.Count++;
|
|
repeatContext.Start = num;
|
|
this.deep = repeatContext;
|
|
if (!this.Eval(Interpreter.Mode.Match, ref num, repeatContext.Expression))
|
|
{
|
|
repeatContext.Count--;
|
|
repeatContext.Start = start2;
|
|
this.Backtrack(num15);
|
|
break;
|
|
}
|
|
if (this.deep != repeatContext)
|
|
{
|
|
this.stack.Count = count2;
|
|
goto IL_FF3;
|
|
}
|
|
this.stack.Push(num15);
|
|
this.stack.Push(num16);
|
|
if (num == repeatContext.Start)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
this.repeat = repeatContext.Previous;
|
|
for (;;)
|
|
{
|
|
this.deep = null;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc + 1))
|
|
{
|
|
break;
|
|
}
|
|
if (this.stack.Count == count2)
|
|
{
|
|
goto Block_88;
|
|
}
|
|
repeatContext.Count--;
|
|
num = this.stack.Pop();
|
|
this.Backtrack(this.stack.Pop());
|
|
}
|
|
this.stack.Count = count2;
|
|
goto IL_FF3;
|
|
}
|
|
IL_C6F:
|
|
this.fast = new Interpreter.RepeatContext(this.fast, this.ReadProgramCount(pc + 2), this.ReadProgramCount(pc + 4), (ushort)(opFlags & OpFlags.Lazy) != 0, pc + 6);
|
|
this.fast.Start = num;
|
|
int num17 = this.Checkpoint();
|
|
pc += (int)this.program[pc + 1];
|
|
ushort num18 = this.program[pc];
|
|
int num19 = -1;
|
|
int num20 = -1;
|
|
int num21 = 0;
|
|
OpCode opCode3 = (OpCode)(num18 & 255);
|
|
if (opCode3 == OpCode.Character || opCode3 == OpCode.String)
|
|
{
|
|
OpFlags opFlags2 = (OpFlags)(num18 & 65280);
|
|
if ((ushort)(opFlags2 & OpFlags.Negate) == 0)
|
|
{
|
|
if (opCode3 == OpCode.String)
|
|
{
|
|
int num22 = 0;
|
|
if ((ushort)(opFlags2 & OpFlags.RightToLeft) != 0)
|
|
{
|
|
num22 = (int)(this.program[pc + 1] - 1);
|
|
}
|
|
num19 = (int)this.program[pc + 2 + num22];
|
|
}
|
|
else
|
|
{
|
|
num19 = (int)this.program[pc + 1];
|
|
}
|
|
if ((ushort)(opFlags2 & OpFlags.IgnoreCase) != 0)
|
|
{
|
|
num20 = (int)char.ToUpper((char)num19);
|
|
}
|
|
else
|
|
{
|
|
num20 = num19;
|
|
}
|
|
if ((ushort)(opFlags2 & OpFlags.RightToLeft) != 0)
|
|
{
|
|
num21 = -1;
|
|
}
|
|
else
|
|
{
|
|
num21 = 0;
|
|
}
|
|
}
|
|
}
|
|
if (this.fast.IsLazy)
|
|
{
|
|
if (!this.fast.IsMinimum && !this.Eval(Interpreter.Mode.Count, ref num, this.fast.Expression))
|
|
{
|
|
goto Block_97;
|
|
}
|
|
for (;;)
|
|
{
|
|
int num23 = num + num21;
|
|
if (num19 < 0 || (num23 >= 0 && num23 < this.text_end && (num19 == (int)this.text[num23] || num20 == (int)this.text[num23])))
|
|
{
|
|
this.deep = null;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (this.fast.IsMaximum)
|
|
{
|
|
goto Block_103;
|
|
}
|
|
this.Backtrack(num17);
|
|
if (!this.Eval(Interpreter.Mode.Count, ref num, this.fast.Expression))
|
|
{
|
|
goto Block_104;
|
|
}
|
|
}
|
|
this.fast = this.fast.Previous;
|
|
goto IL_FF3;
|
|
}
|
|
else
|
|
{
|
|
if (!this.Eval(Interpreter.Mode.Count, ref num, this.fast.Expression))
|
|
{
|
|
goto Block_105;
|
|
}
|
|
int num24;
|
|
if (this.fast.Count > 0)
|
|
{
|
|
num24 = (num - this.fast.Start) / this.fast.Count;
|
|
}
|
|
else
|
|
{
|
|
num24 = 0;
|
|
}
|
|
for (;;)
|
|
{
|
|
int num25 = num + num21;
|
|
if (num19 < 0 || (num25 >= 0 && num25 < this.text_end && (num19 == (int)this.text[num25] || num20 == (int)this.text[num25])))
|
|
{
|
|
this.deep = null;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
this.fast.Count--;
|
|
if (!this.fast.IsMinimum)
|
|
{
|
|
goto Block_112;
|
|
}
|
|
num -= num24;
|
|
this.Backtrack(num17);
|
|
}
|
|
this.fast = this.fast.Previous;
|
|
goto IL_FF3;
|
|
}
|
|
}
|
|
IL_4B8:
|
|
Block_44:
|
|
Block_46:
|
|
Block_47:
|
|
Block_49:
|
|
Block_52:
|
|
Block_54:
|
|
Block_55:
|
|
Block_57:
|
|
Block_59:
|
|
Block_61:
|
|
Block_62:
|
|
Block_63:
|
|
Block_65:
|
|
Block_67:
|
|
Block_70:
|
|
goto IL_1067;
|
|
IL_941:
|
|
this.repeat = this.repeat.Previous;
|
|
goto IL_1067;
|
|
Block_73:
|
|
repeatContext.Start = start;
|
|
repeatContext.Count = count;
|
|
goto IL_1067;
|
|
IL_A28:
|
|
this.repeat = repeatContext;
|
|
Block_80:
|
|
goto IL_1067;
|
|
Block_81:
|
|
repeatContext.Start = start;
|
|
repeatContext.Count = count;
|
|
Block_83:
|
|
goto IL_1067;
|
|
Block_88:
|
|
this.repeat = repeatContext;
|
|
goto IL_1067;
|
|
Block_97:
|
|
this.fast = this.fast.Previous;
|
|
goto IL_1067;
|
|
Block_103:
|
|
this.fast = this.fast.Previous;
|
|
goto IL_1067;
|
|
Block_104:
|
|
this.fast = this.fast.Previous;
|
|
goto IL_1067;
|
|
Block_105:
|
|
this.fast = this.fast.Previous;
|
|
goto IL_1067;
|
|
Block_112:
|
|
this.fast = this.fast.Previous;
|
|
IL_FE9:
|
|
IL_1067:
|
|
if (mode == Interpreter.Mode.Match)
|
|
{
|
|
return false;
|
|
}
|
|
if (mode != Interpreter.Mode.Count)
|
|
{
|
|
return false;
|
|
}
|
|
if (!this.fast.IsLazy && this.fast.IsMinimum)
|
|
{
|
|
return true;
|
|
}
|
|
ref_ptr = this.fast.Start;
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x06001A1F RID: 6687 RVA: 0x0005E434 File Offset: 0x0005C634
|
|
private bool EvalChar(Interpreter.Mode mode, ref int ptr, ref int pc, bool multi)
|
|
{
|
|
bool flag = false;
|
|
char c = '\0';
|
|
bool flag3;
|
|
for (;;)
|
|
{
|
|
ushort num = this.program[pc];
|
|
OpCode opCode = (OpCode)(num & 255);
|
|
OpFlags opFlags = (OpFlags)(num & 65280);
|
|
pc++;
|
|
bool flag2 = (ushort)(opFlags & OpFlags.IgnoreCase) != 0;
|
|
if (!flag)
|
|
{
|
|
if ((ushort)(opFlags & OpFlags.RightToLeft) != 0)
|
|
{
|
|
if (ptr <= 0)
|
|
{
|
|
break;
|
|
}
|
|
c = this.text[--ptr];
|
|
}
|
|
else
|
|
{
|
|
if (ptr >= this.text_end)
|
|
{
|
|
return false;
|
|
}
|
|
c = this.text[ptr++];
|
|
}
|
|
if (flag2)
|
|
{
|
|
c = char.ToLower(c);
|
|
}
|
|
flag = true;
|
|
}
|
|
flag3 = (ushort)(opFlags & OpFlags.Negate) != 0;
|
|
switch (opCode)
|
|
{
|
|
case OpCode.False:
|
|
return false;
|
|
case OpCode.True:
|
|
return true;
|
|
case OpCode.Character:
|
|
if (c == (char)this.program[pc++])
|
|
{
|
|
goto Block_7;
|
|
}
|
|
break;
|
|
case OpCode.Category:
|
|
if (CategoryUtils.IsCategory((Category)this.program[pc++], c))
|
|
{
|
|
goto Block_8;
|
|
}
|
|
break;
|
|
case OpCode.NotCategory:
|
|
if (!CategoryUtils.IsCategory((Category)this.program[pc++], c))
|
|
{
|
|
goto Block_9;
|
|
}
|
|
break;
|
|
case OpCode.Range:
|
|
{
|
|
int num2 = (int)this.program[pc++];
|
|
int num3 = (int)this.program[pc++];
|
|
if (num2 <= (int)c && (int)c <= num3)
|
|
{
|
|
goto Block_11;
|
|
}
|
|
break;
|
|
}
|
|
case OpCode.Set:
|
|
{
|
|
int num4 = (int)this.program[pc++];
|
|
int num5 = (int)this.program[pc++];
|
|
int num6 = pc;
|
|
pc += num5;
|
|
int num7 = (int)c - num4;
|
|
if (num7 >= 0 && num7 < num5 << 4)
|
|
{
|
|
if (((int)this.program[num6 + (num7 >> 4)] & (1 << (num7 & 15))) != 0)
|
|
{
|
|
goto Block_13;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (!multi)
|
|
{
|
|
return flag3;
|
|
}
|
|
}
|
|
return false;
|
|
Block_7:
|
|
return !flag3;
|
|
Block_8:
|
|
return !flag3;
|
|
Block_9:
|
|
return !flag3;
|
|
Block_11:
|
|
return !flag3;
|
|
Block_13:
|
|
return !flag3;
|
|
}
|
|
|
|
// Token: 0x06001A20 RID: 6688 RVA: 0x0005E66C File Offset: 0x0005C86C
|
|
private bool TryMatch(ref int ref_ptr, int pc)
|
|
{
|
|
this.Reset();
|
|
int num = ref_ptr;
|
|
this.marks[this.groups[0]].Start = num;
|
|
if (this.Eval(Interpreter.Mode.Match, ref num, pc))
|
|
{
|
|
this.marks[this.groups[0]].End = num;
|
|
ref_ptr = num;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x06001A21 RID: 6689 RVA: 0x0005E6CC File Offset: 0x0005C8CC
|
|
private bool IsPosition(Position pos, int ptr)
|
|
{
|
|
switch (pos)
|
|
{
|
|
case Position.Start:
|
|
case Position.StartOfString:
|
|
return ptr == 0;
|
|
case Position.StartOfLine:
|
|
return ptr == 0 || this.text[ptr - 1] == '\n';
|
|
case Position.StartOfScan:
|
|
return ptr == this.scan_ptr;
|
|
case Position.End:
|
|
return ptr == this.text_end || (ptr == this.text_end - 1 && this.text[ptr] == '\n');
|
|
case Position.EndOfString:
|
|
return ptr == this.text_end;
|
|
case Position.EndOfLine:
|
|
return ptr == this.text_end || this.text[ptr] == '\n';
|
|
case Position.Boundary:
|
|
if (this.text_end == 0)
|
|
{
|
|
return false;
|
|
}
|
|
if (ptr == 0)
|
|
{
|
|
return this.IsWordChar(this.text[ptr]);
|
|
}
|
|
if (ptr == this.text_end)
|
|
{
|
|
return this.IsWordChar(this.text[ptr - 1]);
|
|
}
|
|
return this.IsWordChar(this.text[ptr]) != this.IsWordChar(this.text[ptr - 1]);
|
|
case Position.NonBoundary:
|
|
if (this.text_end == 0)
|
|
{
|
|
return false;
|
|
}
|
|
if (ptr == 0)
|
|
{
|
|
return !this.IsWordChar(this.text[ptr]);
|
|
}
|
|
if (ptr == this.text_end)
|
|
{
|
|
return !this.IsWordChar(this.text[ptr - 1]);
|
|
}
|
|
return this.IsWordChar(this.text[ptr]) == this.IsWordChar(this.text[ptr - 1]);
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06001A22 RID: 6690 RVA: 0x0005E87C File Offset: 0x0005CA7C
|
|
private bool IsWordChar(char c)
|
|
{
|
|
return CategoryUtils.IsCategory(Category.Word, c);
|
|
}
|
|
|
|
// Token: 0x06001A23 RID: 6691 RVA: 0x0005E888 File Offset: 0x0005CA88
|
|
private string GetString(int pc)
|
|
{
|
|
int num = (int)this.program[pc + 1];
|
|
int num2 = pc + 2;
|
|
char[] array = new char[num];
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
array[i] = (char)this.program[num2++];
|
|
}
|
|
return new string(array);
|
|
}
|
|
|
|
// Token: 0x06001A24 RID: 6692 RVA: 0x0005E8D4 File Offset: 0x0005CAD4
|
|
private void Open(int gid, int ptr)
|
|
{
|
|
int num = this.groups[gid];
|
|
if (num < this.mark_start || this.marks[num].IsDefined)
|
|
{
|
|
num = this.CreateMark(num);
|
|
this.groups[gid] = num;
|
|
}
|
|
this.marks[num].Start = ptr;
|
|
}
|
|
|
|
// Token: 0x06001A25 RID: 6693 RVA: 0x0005E930 File Offset: 0x0005CB30
|
|
private void Close(int gid, int ptr)
|
|
{
|
|
this.marks[this.groups[gid]].End = ptr;
|
|
}
|
|
|
|
// Token: 0x06001A26 RID: 6694 RVA: 0x0005E94C File Offset: 0x0005CB4C
|
|
private bool Balance(int gid, int balance_gid, bool capture, int ptr)
|
|
{
|
|
int num = this.groups[balance_gid];
|
|
if (num == -1 || this.marks[num].Index < 0)
|
|
{
|
|
return false;
|
|
}
|
|
if (gid > 0 && capture)
|
|
{
|
|
this.Open(gid, this.marks[num].Index + this.marks[num].Length);
|
|
this.Close(gid, ptr);
|
|
}
|
|
this.groups[balance_gid] = this.marks[num].Previous;
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x06001A27 RID: 6695 RVA: 0x0005E9DC File Offset: 0x0005CBDC
|
|
private int Checkpoint()
|
|
{
|
|
this.mark_start = this.mark_end;
|
|
return this.mark_start;
|
|
}
|
|
|
|
// Token: 0x06001A28 RID: 6696 RVA: 0x0005E9F0 File Offset: 0x0005CBF0
|
|
private void Backtrack(int cp)
|
|
{
|
|
for (int i = 0; i < this.groups.Length; i++)
|
|
{
|
|
int num = this.groups[i];
|
|
while (cp <= num)
|
|
{
|
|
num = this.marks[num].Previous;
|
|
}
|
|
this.groups[i] = num;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06001A29 RID: 6697 RVA: 0x0005EA48 File Offset: 0x0005CC48
|
|
private void ResetGroups()
|
|
{
|
|
int num = this.groups.Length;
|
|
if (this.marks == null)
|
|
{
|
|
this.marks = new Mark[num * 10];
|
|
}
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
this.groups[i] = i;
|
|
this.marks[i].Start = -1;
|
|
this.marks[i].End = -1;
|
|
this.marks[i].Previous = -1;
|
|
}
|
|
this.mark_start = 0;
|
|
this.mark_end = num;
|
|
}
|
|
|
|
// Token: 0x06001A2A RID: 6698 RVA: 0x0005EAD8 File Offset: 0x0005CCD8
|
|
private int GetLastDefined(int gid)
|
|
{
|
|
int num = this.groups[gid];
|
|
while (num >= 0 && !this.marks[num].IsDefined)
|
|
{
|
|
num = this.marks[num].Previous;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
// Token: 0x06001A2B RID: 6699 RVA: 0x0005EB24 File Offset: 0x0005CD24
|
|
private int CreateMark(int previous)
|
|
{
|
|
if (this.mark_end == this.marks.Length)
|
|
{
|
|
Mark[] array = new Mark[this.marks.Length * 2];
|
|
this.marks.CopyTo(array, 0);
|
|
this.marks = array;
|
|
}
|
|
int num = this.mark_end++;
|
|
this.marks[num].Start = (this.marks[num].End = -1);
|
|
this.marks[num].Previous = previous;
|
|
return num;
|
|
}
|
|
|
|
// Token: 0x06001A2C RID: 6700 RVA: 0x0005EBB4 File Offset: 0x0005CDB4
|
|
private void GetGroupInfo(int gid, out int first_mark_index, out int n_caps)
|
|
{
|
|
first_mark_index = -1;
|
|
n_caps = 0;
|
|
for (int i = this.groups[gid]; i >= 0; i = this.marks[i].Previous)
|
|
{
|
|
if (this.marks[i].IsDefined)
|
|
{
|
|
if (first_mark_index < 0)
|
|
{
|
|
first_mark_index = i;
|
|
}
|
|
n_caps++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06001A2D RID: 6701 RVA: 0x0005EC1C File Offset: 0x0005CE1C
|
|
private void PopulateGroup(Group g, int first_mark_index, int n_caps)
|
|
{
|
|
int num = 1;
|
|
for (int i = this.marks[first_mark_index].Previous; i >= 0; i = this.marks[i].Previous)
|
|
{
|
|
if (this.marks[i].IsDefined)
|
|
{
|
|
Capture capture = new Capture(this.text, this.marks[i].Index, this.marks[i].Length);
|
|
g.Captures.SetValue(capture, n_caps - 1 - num);
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06001A2E RID: 6702 RVA: 0x0005ECBC File Offset: 0x0005CEBC
|
|
private Match GenerateMatch(Regex regex)
|
|
{
|
|
int num;
|
|
int num2;
|
|
this.GetGroupInfo(0, out num, out num2);
|
|
if (!this.needs_groups_or_captures)
|
|
{
|
|
return new Match(regex, this, this.text, this.text_end, 0, this.marks[num].Index, this.marks[num].Length);
|
|
}
|
|
Match match = new Match(regex, this, this.text, this.text_end, this.groups.Length, this.marks[num].Index, this.marks[num].Length, num2);
|
|
this.PopulateGroup(match, num, num2);
|
|
for (int i = 1; i < this.groups.Length; i++)
|
|
{
|
|
this.GetGroupInfo(i, out num, out num2);
|
|
Group group;
|
|
if (num < 0)
|
|
{
|
|
group = Group.Fail;
|
|
}
|
|
else
|
|
{
|
|
group = new Group(this.text, this.marks[num].Index, this.marks[num].Length, num2);
|
|
this.PopulateGroup(group, num, num2);
|
|
}
|
|
match.Groups.SetValue(group, i);
|
|
}
|
|
return match;
|
|
}
|
|
|
|
// Token: 0x0400157C RID: 5500
|
|
private ushort[] program;
|
|
|
|
// Token: 0x0400157D RID: 5501
|
|
private int program_start;
|
|
|
|
// Token: 0x0400157E RID: 5502
|
|
private string text;
|
|
|
|
// Token: 0x0400157F RID: 5503
|
|
private int text_end;
|
|
|
|
// Token: 0x04001580 RID: 5504
|
|
private int group_count;
|
|
|
|
// Token: 0x04001581 RID: 5505
|
|
private int match_min;
|
|
|
|
// Token: 0x04001582 RID: 5506
|
|
private QuickSearch qs;
|
|
|
|
// Token: 0x04001583 RID: 5507
|
|
private int scan_ptr;
|
|
|
|
// Token: 0x04001584 RID: 5508
|
|
private Interpreter.RepeatContext repeat;
|
|
|
|
// Token: 0x04001585 RID: 5509
|
|
private Interpreter.RepeatContext fast;
|
|
|
|
// Token: 0x04001586 RID: 5510
|
|
private Interpreter.IntStack stack = default(Interpreter.IntStack);
|
|
|
|
// Token: 0x04001587 RID: 5511
|
|
private Interpreter.RepeatContext deep;
|
|
|
|
// Token: 0x04001588 RID: 5512
|
|
private Mark[] marks;
|
|
|
|
// Token: 0x04001589 RID: 5513
|
|
private int mark_start;
|
|
|
|
// Token: 0x0400158A RID: 5514
|
|
private int mark_end;
|
|
|
|
// Token: 0x0400158B RID: 5515
|
|
private int[] groups;
|
|
|
|
// Token: 0x020002CF RID: 719
|
|
private struct IntStack
|
|
{
|
|
// Token: 0x06001A2F RID: 6703 RVA: 0x0005EDE0 File Offset: 0x0005CFE0
|
|
public int Pop()
|
|
{
|
|
return this.values[--this.count];
|
|
}
|
|
|
|
// Token: 0x06001A30 RID: 6704 RVA: 0x0005EE08 File Offset: 0x0005D008
|
|
public void Push(int value)
|
|
{
|
|
if (this.values == null)
|
|
{
|
|
this.values = new int[8];
|
|
}
|
|
else if (this.count == this.values.Length)
|
|
{
|
|
int num = this.values.Length;
|
|
num += num >> 1;
|
|
int[] array = new int[num];
|
|
for (int i = 0; i < this.count; i++)
|
|
{
|
|
array[i] = this.values[i];
|
|
}
|
|
this.values = array;
|
|
}
|
|
this.values[this.count++] = value;
|
|
}
|
|
|
|
// Token: 0x1700080B RID: 2059
|
|
// (get) Token: 0x06001A31 RID: 6705 RVA: 0x0005EE9C File Offset: 0x0005D09C
|
|
public int Top
|
|
{
|
|
get
|
|
{
|
|
return this.values[this.count - 1];
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700080C RID: 2060
|
|
// (get) Token: 0x06001A32 RID: 6706 RVA: 0x0005EEB0 File Offset: 0x0005D0B0
|
|
// (set) Token: 0x06001A33 RID: 6707 RVA: 0x0005EEB8 File Offset: 0x0005D0B8
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
return this.count;
|
|
}
|
|
set
|
|
{
|
|
if (value > this.count)
|
|
{
|
|
throw new SystemException("can only truncate the stack");
|
|
}
|
|
this.count = value;
|
|
}
|
|
}
|
|
|
|
// Token: 0x0400158C RID: 5516
|
|
private int[] values;
|
|
|
|
// Token: 0x0400158D RID: 5517
|
|
private int count;
|
|
}
|
|
|
|
// Token: 0x020002D0 RID: 720
|
|
private class RepeatContext
|
|
{
|
|
// Token: 0x06001A34 RID: 6708 RVA: 0x0005EED8 File Offset: 0x0005D0D8
|
|
public RepeatContext(Interpreter.RepeatContext previous, int min, int max, bool lazy, int expr_pc)
|
|
{
|
|
this.previous = previous;
|
|
this.min = min;
|
|
this.max = max;
|
|
this.lazy = lazy;
|
|
this.expr_pc = expr_pc;
|
|
this.start = -1;
|
|
this.count = 0;
|
|
}
|
|
|
|
// Token: 0x1700080D RID: 2061
|
|
// (get) Token: 0x06001A35 RID: 6709 RVA: 0x0005EF14 File Offset: 0x0005D114
|
|
// (set) Token: 0x06001A36 RID: 6710 RVA: 0x0005EF1C File Offset: 0x0005D11C
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
return this.count;
|
|
}
|
|
set
|
|
{
|
|
this.count = value;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700080E RID: 2062
|
|
// (get) Token: 0x06001A37 RID: 6711 RVA: 0x0005EF28 File Offset: 0x0005D128
|
|
// (set) Token: 0x06001A38 RID: 6712 RVA: 0x0005EF30 File Offset: 0x0005D130
|
|
public int Start
|
|
{
|
|
get
|
|
{
|
|
return this.start;
|
|
}
|
|
set
|
|
{
|
|
this.start = value;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700080F RID: 2063
|
|
// (get) Token: 0x06001A39 RID: 6713 RVA: 0x0005EF3C File Offset: 0x0005D13C
|
|
public bool IsMinimum
|
|
{
|
|
get
|
|
{
|
|
return this.min <= this.count;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000810 RID: 2064
|
|
// (get) Token: 0x06001A3A RID: 6714 RVA: 0x0005EF50 File Offset: 0x0005D150
|
|
public bool IsMaximum
|
|
{
|
|
get
|
|
{
|
|
return this.max <= this.count;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000811 RID: 2065
|
|
// (get) Token: 0x06001A3B RID: 6715 RVA: 0x0005EF64 File Offset: 0x0005D164
|
|
public bool IsLazy
|
|
{
|
|
get
|
|
{
|
|
return this.lazy;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000812 RID: 2066
|
|
// (get) Token: 0x06001A3C RID: 6716 RVA: 0x0005EF6C File Offset: 0x0005D16C
|
|
public int Expression
|
|
{
|
|
get
|
|
{
|
|
return this.expr_pc;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000813 RID: 2067
|
|
// (get) Token: 0x06001A3D RID: 6717 RVA: 0x0005EF74 File Offset: 0x0005D174
|
|
public Interpreter.RepeatContext Previous
|
|
{
|
|
get
|
|
{
|
|
return this.previous;
|
|
}
|
|
}
|
|
|
|
// Token: 0x0400158E RID: 5518
|
|
private int start;
|
|
|
|
// Token: 0x0400158F RID: 5519
|
|
private int min;
|
|
|
|
// Token: 0x04001590 RID: 5520
|
|
private int max;
|
|
|
|
// Token: 0x04001591 RID: 5521
|
|
private bool lazy;
|
|
|
|
// Token: 0x04001592 RID: 5522
|
|
private int expr_pc;
|
|
|
|
// Token: 0x04001593 RID: 5523
|
|
private Interpreter.RepeatContext previous;
|
|
|
|
// Token: 0x04001594 RID: 5524
|
|
private int count;
|
|
}
|
|
|
|
// Token: 0x020002D1 RID: 721
|
|
private enum Mode
|
|
{
|
|
// Token: 0x04001596 RID: 5526
|
|
Search,
|
|
// Token: 0x04001597 RID: 5527
|
|
Match,
|
|
// Token: 0x04001598 RID: 5528
|
|
Count
|
|
}
|
|
}
|
|
}
|