From ac1e7c68f8d2da4ddb0141826a1cde8e592a517d Mon Sep 17 00:00:00 2001
From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com>
Date: Mon, 27 Jul 2026 18:11:31 +0800
Subject: [PATCH] mainly theoratical work on semi, add regex sample
---
src/StgSharp.RegularAnalysis/Text/RegexIR.cs | 8 ++--
.../TextRegexSourceGen.GenClass.MultiIR.cs | 23 +++++++++-
.../Text/TextRegexSourceGen.GenContext.cs | 20 +++++++++
test/SingleFile/regex.cs | 44 +++++++++++++++++++
test/StgSharpDebug/TestRegexAnalyse.cs | 2 +-
5 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/src/StgSharp.RegularAnalysis/Text/RegexIR.cs b/src/StgSharp.RegularAnalysis/Text/RegexIR.cs
index 2bb3dbc6..a026fe2e 100644
--- a/src/StgSharp.RegularAnalysis/Text/RegexIR.cs
+++ b/src/StgSharp.RegularAnalysis/Text/RegexIR.cs
@@ -73,12 +73,14 @@ namespace StgSharp.RegularAnalysis.Text
}
+ internal interface IRegexMatch { }
+
///
/// Searches for a certain string pattern or charset from current position.
///
internal sealed class RegexMatchSeqIR(
string pattern
- ) : RegexIR(RegexIRCommand.Match_Seq), IRegexSequence
+ ) : RegexIR(RegexIRCommand.Match_Seq), IRegexSequence, IRegexMatch
{
public string Pattern { get; } = pattern;
@@ -92,7 +94,7 @@ namespace StgSharp.RegularAnalysis.Text
internal sealed class RegexMatchSetIR(
string charset
- ) : RegexIR(RegexIRCommand.Match_Set)
+ ) : RegexIR(RegexIRCommand.Match_Set), IRegexMatch
{
public string Charset { get; } = charset;
@@ -225,7 +227,7 @@ namespace StgSharp.RegularAnalysis.Text
internal sealed class RegexTryIR(
int count
- ) : RegexIR(RegexIRCommand.Try), IRegexComplex
+ ) : RegexIR(RegexIRCommand.Try), IRegexComplex, IRegexMatch
{
public bool IsFullyOptimized { get; set; }
diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.MultiIR.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.MultiIR.cs
index 4b8cc1e8..09e58abb 100644
--- a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.MultiIR.cs
+++ b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.MultiIR.cs
@@ -19,6 +19,24 @@ namespace StgSharp.RegularAnalysis.Text
internal partial class TextRegexSourceGen
{
+ private static int GenerateNamedCountAny(
+ ReadOnlySpan region_ir,
+ SourceGenContext sc,
+ in SequenceEmitter main_emitter,
+ in List> sub_emitter_list
+ )
+ {
+ if (region_ir[0] is not RegexCountSetIR { IsDotStar:true} ||
+ region_ir[1] is not RegexPackIR pack) {
+ return -1;
+ }
+ if (region_ir[2] is RegexMatchSeqIR) { }
+ _ = main_emitter.AppendLine($@"do").AppendLine($@"{{");
+ _ = main_emitter.AppendLine($@"}}").AppendLine($@"while(true);");
+ string group_idx = sc.MakeNewNamedGroup(pack.GroupName);
+ return 0;
+ }
+
private static void GenerateRegion(
ReadOnlySpan region_ir,
SourceGenContext sc,
@@ -35,7 +53,8 @@ namespace StgSharp.RegularAnalysis.Text
int result;
int count = 0;
scan_win = ir_sp[index..];
- if ((result = TryGenerateFindSeq(scan_win, sc, in main_emitter,
+ if ((result =
+ TryGenerateFindSeq(scan_win, sc, in main_emitter,
in sub_emitter_list)) > 0)
{
count += result;
@@ -77,7 +96,7 @@ namespace StgSharp.RegularAnalysis.Text
if (scan_win[1] is RegexMatchSeqIR seq)
{
- string seq_pat = FormatStringLiteral(find.Pattern + seq.Pattern);
+ string seq_pat = FormatStringLiteral($"{find.Pattern}{seq.Pattern}");
_ = main_emitter.AppendLine(@$"//Match sequence:{seq_pat} at current pos")
.AppendLine($@"if( )");
}
diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs
index daf78781..0b8a89e0 100644
--- a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs
+++ b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenContext.cs
@@ -50,6 +50,26 @@ namespace StgSharp.RegularAnalysis.Text
}
}
+ #region namig group
+
+ private int _min_named_group;
+ private Dictionary _name_idx_map = [];
+
+ public string MakeNewNamedGroup(
+ string name
+ )
+ {
+ if (_name_idx_map.TryGetValue(name, out int idx)) {
+ return $"__named_group_{idx}";
+ }
+ idx = _min_named_group;
+ _name_idx_map[name] = idx;
+ _min_named_group++;
+ return $"__named_group_{idx}";
+ }
+
+ #endregion
+
public string FindResult
{
get
diff --git a/test/SingleFile/regex.cs b/test/SingleFile/regex.cs
index b74b5ae5..04992e06 100644
--- a/test/SingleFile/regex.cs
+++ b/test/SingleFile/regex.cs
@@ -122,3 +122,47 @@ static void Match_AB_2_3(ReadOnlySpan input)
} while(false);
}
+
+// (ab|[cd]|.)x
+static void MatchDiffCase(ReadOnlySpan seq)
+{
+ /*
+ * [000] 0001, DEF , Sccs, NONE, 0000, MATCH_SEQ "ab"
+ * [001] 0001, Fail, Sccs, LINE, 0000, MATCH_SET "[cd]"
+ * [002] 0001, Fail, Sccs, LINE, 0001, MATCH_SET "."
+ * [003] 0000, Fail, DEF , LINE, 0002, POP FAIL
+ * [004] 0000, DEF , DEF , NONE, 0000, MATCH_SEQ "x"
+ */
+
+ int ptr = 0;
+ if(seq.StartsWith("ab"))
+ {
+ ptr+=2;
+ }
+ else if((seq[0] == 'c' || seq[0] == 'd'))
+ {
+ ptr+=1;
+ }
+ else if(true)
+ {
+ ptr+=1;
+ }
+ else
+ {
+ return;
+ }
+}
+
+// (?.*)x
+static void MatchCountAnyGroup(ReadOnlySpan seq)
+{
+ /*
+ * [000] 0001, DEF , DEF , NONE, 0000, FIND_COMPLEX FURTHEST COUNT: -1
+ * [001] 0001, Sccs, DEF , LINE, 0000, PACK SUCCESS GROUP: "name"
+ * [002] 0000, DEF , DEF , NONE, 0000, MATCH_SEQ "234"
+ */
+
+ int ptr = 0;
+
+
+}
\ No newline at end of file
diff --git a/test/StgSharpDebug/TestRegexAnalyse.cs b/test/StgSharpDebug/TestRegexAnalyse.cs
index 92bf99a6..e01bbcc7 100644
--- a/test/StgSharpDebug/TestRegexAnalyse.cs
+++ b/test/StgSharpDebug/TestRegexAnalyse.cs
@@ -21,7 +21,7 @@ namespace StgSharp
{
private static string[] regexSource = [
- @"(?123)(?123)",
+ @"(?.*)234",
/*
@"http|https|ftp|ftps",
@"abc[0-9]x|abc[0-9]y|abd[0-9]x|abd[0-9]y|xyz",