add some generator decl

This commit is contained in:
Youmu Liu
2026-07-30 18:13:21 +08:00
parent 97576404cc
commit 85ca22d1aa
2 changed files with 80 additions and 48 deletions
@@ -8,60 +8,13 @@
using StgSharp.RegularAnalysis.Abstraction;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.Threading;
namespace StgSharp.RegularAnalysis.Text
{
internal partial class TextRegexSourceGen
{
private static int TryGenerateAltChain(
int outer_level,
ReadOnlySpan<RegexIR> ir_span,
SourceGenContext sc,
in SequenceEmitter<string> code,
in List<SequenceEmitter<string>> local_func
)
{
/*
* L1.1 ALT chain
* window region, then further regions carrying Prev_Fail
* mirrors TryEmitAltChain
* shape if / else if / else
* sample a|b, ab|cd|ef, a|bc|def
* nature flattening, may return -1
*/
/*
* [004] 0001, DEF , DEF , NONE, 0000, MATCH_SEQ "abc"
* [005] 0002, DEF , Sccs, NONE, 0000, MATCH_SEQ "d" <- an alt chain begins here
* [006] 0002, Fail, Sccs, LINE, 0005, MATCH_SEQ "c" <- an alt chain ends here
* [007] 0001, Fail, DEF , LINE, 0006, POP FAIL
*/
const RegexIRPrefixMask simple_alt = RegexIRPrefixMask.Prev_Fail | RegexIRPrefixMask.Pop_Success;
int cur_level = ir_span[0].Prefix.WorkingRegion;
if (cur_level == outer_level) {
return -1;
}
int i = 1;
RegexIR ir;
for (; i < ir_span.Length; i++)
{
ir = ir_span[i];
if ((ir.Prefix.Mask & simple_alt) == simple_alt)
{
// simple match
} else if (ir is RegexTryIR _try && (ir.Prefix.Mask & simple_alt) == simple_alt)
{
// match a try region
ReadOnlySpan<RegexIR> body_span = ir_span.Slice(i + 1, i + _try.CommandCount);
i += _try.CommandCount;
}
}
return i;
}
/*
* =======================================================================================
* L1, several regions plus a tail
@@ -241,6 +194,8 @@ namespace StgSharp.RegularAnalysis.Text
* - a merged window still has to leave __ok describing the whole window
*/
#region code
private static int TryGenerateTryBlock(
int outer_level,
ReadOnlySpan<RegexIR> ir_span,
@@ -258,5 +213,81 @@ namespace StgSharp.RegularAnalysis.Text
return _try.CommandCount;
}
private static int TryGenerateNamedCountAny(
int outer_level,
ReadOnlySpan<RegexIR> ir_span,
SourceGenContext sc,
in SequenceEmitter<string> code,
in List<SequenceEmitter<string>> local_func
)
{
/*
* (?<name>.*)234
* [010] 0003, DEF , DEF , NONE, 0000, FIND_COMPLEX FURTHEST COUNT: -1
* [011] 0003, Sccs, DEF , LINE, 0010, PACK SUCCESS GROUP: "name"
* [012] 0000, DEF , DEF , NONE, 0000, MATCH_SEQ "234"
*/
if (ir_span[0] is not RegexCountSetIR { IsDotStar:true} ||
ir_span[1] is not RegexPackIR pack)
{
return -1;
}
string group_name = pack.GroupName;
int i = 0;
for (; i < ir_span.Length; i++) { }
return -1;
}
private static int TryGenerateAltChain(
int outer_level,
ReadOnlySpan<RegexIR> ir_span,
SourceGenContext sc,
in SequenceEmitter<string> code,
in List<SequenceEmitter<string>> local_func
)
{
/*
* L1.1 ALT chain
* window region, then further regions carrying Prev_Fail
* mirrors TryEmitAltChain
* shape if / else if / else
* sample a|b, ab|cd|ef, a|bc|def
* nature flattening, may return -1
*/
/*
* [004] 0001, DEF , DEF , NONE, 0000, MATCH_SEQ "abc"
* [005] 0002, DEF , Sccs, NONE, 0000, MATCH_SEQ "d" <- an alt chain begins here
* [006] 0002, Fail, Sccs, LINE, 0005, MATCH_SEQ "c" <- an alt chain ends here
* [007] 0001, Fail, DEF , LINE, 0006, POP FAIL
*/
const RegexIRPrefixMask simple_alt = RegexIRPrefixMask.Prev_Fail | RegexIRPrefixMask.Pop_Success;
int cur_level = ir_span[0].Prefix.WorkingRegion;
if (cur_level == outer_level) {
return -1;
}
int i = 1;
RegexIR ir;
for (; i < ir_span.Length; i++)
{
ir = ir_span[i];
if ((ir.Prefix.Mask & simple_alt) == simple_alt)
{
// simple match
} else if (ir is RegexTryIR _try && (ir.Prefix.Mask & simple_alt) == simple_alt)
{
// match a try region
ReadOnlySpan<RegexIR> body_span = ir_span.Slice(i + 1, i + _try.CommandCount);
i += _try.CommandCount;
}
}
return i;
}
#endregion
}
}
@@ -126,6 +126,7 @@ namespace StgSharp.RegularAnalysis.Text
// GenerateRegion(region, sc, match_e, sub_match_list);
_ = TryGenerateAltChain(0, region, sc, match_e, sub_match_list);
_ = TryGenerateTryBlock(0, region, sc, match_e, sub_match_list);
_ = TryGenerateNamedCountAny(0, region, sc, match_e, sub_match_list);
if (end >= ir_sp.Length)
{
break;