diff --git a/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IROptimize.cs b/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IROptimize.cs index 16c9ebaf..56fb2793 100644 --- a/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IROptimize.cs +++ b/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IROptimize.cs @@ -92,7 +92,13 @@ namespace StgSharp.RegularAnalysis.Text process_count += result; } opt_count++; - } else if (opt_win_sp[0] is RegexTryIR{ IsFullyOptimized:false} try_ir) + } else if (opt_win_sp[0] is IRegexComplex { IsFullyOptimized: true } skip) + { + int count = skip.CommandCount; + process_count += count + 1; + Span opt_block = origin_span.Slice(index, count + 1); + opt_ir.AddRange(opt_block); + } else if (opt_win_sp[0] is RegexTryIR { IsFullyOptimized: false } try_ir) { process_count++; int cmd_cnt = try_ir.CommandCount; @@ -125,6 +131,35 @@ namespace StgSharp.RegularAnalysis.Text opt_ir.Clear(); goto opt_cycle; } + /**/ + (origin_ir, opt_ir) = (opt_ir, origin_ir); + opt_ir.Clear(); + index = 0; + origin_span = CollectionsMarshal.AsSpan(origin_ir); + do + { + int process_count = 0; + int last = int.Min(origin_span.Length, index + 8); + origin_span[index..last].CopyTo(opt_win_sp); + + if (opt_win_sp[0] is IRegexComplex { IsFullyOptimized: true } skip) + { + int count = skip.CommandCount; + process_count += count + 1; + Span opt_block = origin_span.Slice(index, count + 1); + opt_ir.AddRange(opt_block); + } else if (TryReplaceDotStar(opt_win_sp, opt_ir) >= 0) + { + process_count++; + } else + { + opt_ir.Add(opt_win_sp[0]); + process_count++; + } + + index += process_count; + } while (index < origin_ir.Count); + /**/ optIR = opt_ir; } @@ -144,7 +179,7 @@ namespace StgSharp.RegularAnalysis.Text List opt ) { - const int falttern_size = 32; + const int flatten_size = 32; RegexIR ir = window[0]; if (ir is not RegexCountSeqIR seq) { return -1; @@ -156,10 +191,10 @@ namespace StgSharp.RegularAnalysis.Text } string pattern = seq.Sequence; int pattern_size = pattern.Length; - if (pattern_size > falttern_size) { + if (pattern_size > flatten_size) { opt.Add(ir); } - int min_expand = falttern_size / pattern_size; + int min_expand = flatten_size / pattern_size; min_expand = int.Min(min_expand, min); string expand = string.Concat(Enumerable.Repeat(pattern, min_expand)); int new_min = min / min_expand; @@ -210,6 +245,33 @@ namespace StgSharp.RegularAnalysis.Text #endregion + private static int TryReplaceDotStar( + Span window, + List opt + ) + { + if (window[0] is not RegexCountSetIR { IsDotStar: true } dot) { + return -1; + } + if (dot.IsGreedy) + { + RegexFindComplexIR find = new(false, -1) + { + IsFullyOptimized = true + }; + opt.Add(find); + return 0; + } else + { + RegexFindComplexIR find = new(true, -1) + { + IsFullyOptimized = true + }; + opt.Add(find); + return 0; + } + } + internal class RegexInfo { @@ -323,7 +385,7 @@ namespace StgSharp.RegularAnalysis.Text /// /// /// - /// Negative if cannot opt, 0 if match sucessfully, positive if meets an IRgexComplex + /// Negative if cannot opt, 0 if match successfully, positive if meets an IRegexComplex /// interface, need to call TryExpandComplexPlus /// private static int TryExpandPlus(