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",