regex ir opt code on rewrite

This commit is contained in:
Youmu Liu
2026-06-25 19:52:11 +08:00
parent 45f9b04b6d
commit 5cd2b8b4ba
7 changed files with 281 additions and 185 deletions
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="RegexInterpreter.HIRGenerate"
// file="RegexInterpreter.IRGenerate"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
@@ -57,31 +57,30 @@ namespace StgSharp.RegularAnalysis.Text
int min,
int max,
bool isGreedy,
RegexAstNode right
RegexAstNode body
)
{
bool isRightOperator = !RegexAstNode.IsNullOrEmpty(right) &&
(right.Source.Flag & RegexElementLabel.OPERATOR) != 0;
bool is_operator = !RegexAstNode.IsNullOrEmpty(body) &&
(body.Source.Flag & RegexElementLabel.OPERATOR) != 0;
if (isRightOperator) // seq to be count is complex
if (is_operator) // seq to be count is complex
{
ir.EmitCount(min, max, isGreedy, 1);
RegexIRGenerator rightIR = GenerateIRRecursion(right, curDepth + 1);
ir.EmitTry(rightIR.Count);
ir.EmitIRStream(rightIR);
RegexIRGenerator body_ir = GenerateIRRecursion(body, curDepth + 1);
ir.EmitCountComplex(min, max, isGreedy, body_ir.Count);
ir.EmitIRStream(body_ir);
} else
{
RegexElementLabel count_source_mask = right.Source.Flag;
RegexElementLabel count_source_mask = body.Source.Flag;
switch (count_source_mask)
{
case RegexElementLabel.UNIT:
ir.EmitCountSeq(min, max, isGreedy, right.Source.Value);
ir.EmitCountSeq(min, max, isGreedy, body.Source.Value);
break;
case RegexElementLabel.UNIT_SET:
ir.EmitCountSet(min, max, isGreedy, right.Source.Value);
ir.EmitCountSet(min, max, isGreedy, body.Source.Value);
break;
case RegexElementLabel.UNIT_SPAN:
ir.EmitCountSeq(min, max, isGreedy, right.Source.Value);
ir.EmitCountSeq(min, max, isGreedy, body.Source.Value);
break;
default:
throw new InvalidOperationException($"Unexpected regex element type for count operator: {count_source_mask}");
@@ -144,17 +143,17 @@ namespace StgSharp.RegularAnalysis.Text
_ => throw new InvalidOperationException("Unexpected sequence mask for count operator"),
};
ReadOnlySpan<char> count_source_span = count_source;
RegexIRGenerator countIR = new();
RegexIRGenerator count_ir = new();
if (count_source_span[0] == '*') // infinite count
{
EmitCount(curDepth, countIR, 0, -1, isGreedy, seq);
EmitCount(curDepth, count_ir, 0, -1, isGreedy, seq);
} else if (count_source_span[0] == '+') // at least one
{
EmitCount(curDepth, countIR, 1, -1, isGreedy, seq);
EmitCount(curDepth, count_ir, 1, -1, isGreedy, seq);
} else if (count_source_span[0] == '?') // zero or one
{
EmitCount(curDepth, countIR, 0, 1, isGreedy, seq);
EmitCount(curDepth, count_ir, 0, 1, isGreedy, seq);
} else if (count_source_span[0] == '{') // zero or one, non-greedy
{
int comma_pos = count_source_span.IndexOf(',');
@@ -162,7 +161,7 @@ namespace StgSharp.RegularAnalysis.Text
{
if (int.TryParse(count_source[1..(isGreedy ? ^2 : ^1)], out int count))
{
EmitCount(curDepth, countIR, count, count, isGreedy, seq);
EmitCount(curDepth, count_ir, count, count, isGreedy, seq);
} else
{
throw new InvalidCastException($"Invalid count format: {count_source}");
@@ -172,7 +171,7 @@ namespace StgSharp.RegularAnalysis.Text
if (int.TryParse(count_source[1..comma_pos], out int min) &&
int.TryParse(count_source[(comma_pos + 1)..(isGreedy ? ^1 : ^2)], out int max))
{
EmitCount(curDepth, countIR, min, max, isGreedy, seq);
EmitCount(curDepth, count_ir, min, max, isGreedy, seq);
} else
{
throw new InvalidCastException($"Invalid count format: {count_source}");
@@ -183,7 +182,7 @@ namespace StgSharp.RegularAnalysis.Text
throw new InvalidOperationException();
} // unknown count format
return countIR;
return count_ir;
case RegexElementLabel.CONCAT:
RegexIRGenerator concat = new();