//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="RegexInterpreter.IROptimize" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StgSharp.RegularAnalysis.Text { public partial class RegexAnalyzer { internal static RegexInfo ScanAndOptimizeIR( List baseIR, out List optIR ) { int index = 0; List optimizedIR = new(baseIR.Count); List segment = []; RegexInfo info = new(); do { // TODO scan and opt here OptimizeIR(baseIR, ref index, segment, info); optimizedIR.AddRange(segment); index++; } while (index < baseIR.Count); optIR = optimizedIR; return info; } private static void OptimizeDot( RegexCountSetIR root, List ir, ref int index, List optimizedIR, RegexInfo info ) { int next = index + 1; if (next >= ir.Count) { optimizedIR.Clear(); optimizedIR.Add(root); return; } RegexIR nextIR = ir[next]; if (nextIR.Command == RegexIRCommand.Match_Seq) { // opt .*abc style RegexFindSeqIR find = new((nextIR as RegexMatchSeqIR)!.Pattern); optimizedIR.Add(find); info.MinLength += find.Pattern.Length; return; } else { } } private static void OptimizeIR( List ir, ref int index, List optimizedIR, RegexInfo info ) { optimizedIR.Clear(); // TODO optimize here RegexIR root = ir[index]; switch (root.Command) { case RegexIRCommand.Count_Set: RegexCountSetIR count = (root as RegexCountSetIR)!; if (count.CharSet == ".") { // opt for .+ / .* / .{} pattern OptimizeDot(count, ir, ref index, optimizedIR, info); } break; case RegexIRCommand.Match_Seq: info.MinLength += (root as RegexMatchSeqIR)!.Pattern.Length; optimizedIR.Add(root); break; default: optimizedIR.Add(root); break; } } internal class RegexInfo { public int MinLength { get; set; } public int TryDepth { get; set; } } } }