add single ir generator methods
This commit is contained in:
@@ -72,9 +72,9 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
* lives in test/SingleFile/regex.cs.
|
||||
*/
|
||||
|
||||
private const string current_ptr = "cur_ptr_global";
|
||||
private const string offset = "offset";
|
||||
private const string orig_text = "text";
|
||||
// private const string current_ptr = "cur_ptr_global"; // global match cursor
|
||||
// private const string offset = "offset"; //
|
||||
// private const string orig_text = "text"; //
|
||||
|
||||
#region L0 method level
|
||||
|
||||
@@ -155,10 +155,11 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
.AppendLine($@"int region_{i}_end = -1;")
|
||||
.AppendLine($@"bool region_{i}_success;");
|
||||
}
|
||||
|
||||
/*
|
||||
_ = se.AppendLine($@"int {current_ptr} = 0;")
|
||||
.AppendLine($@"int {offset} = 0;")
|
||||
.AppendLine();
|
||||
/**/
|
||||
|
||||
// _ = sc.GenVarDefine(se);
|
||||
|
||||
@@ -177,6 +178,14 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
|
||||
#endregion
|
||||
|
||||
private enum RegionExitMethod
|
||||
{
|
||||
|
||||
Break,
|
||||
Continue
|
||||
|
||||
}
|
||||
|
||||
#region shared helpers
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -224,14 +233,14 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
|
||||
}
|
||||
|
||||
internal record struct RegexCharSet(
|
||||
string Value,
|
||||
CharSetType Type,
|
||||
bool Accept
|
||||
internal record class RegexCharSet(
|
||||
string Value,
|
||||
CharSetType Type,
|
||||
bool Accept
|
||||
)
|
||||
{
|
||||
|
||||
public override readonly string ToString()
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{{value:{Value}, type:{Type}, accept:{Accept}}}";
|
||||
}
|
||||
@@ -244,34 +253,45 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
)
|
||||
{
|
||||
// range or single
|
||||
HashSet<char> single_char = [];
|
||||
if (source[0] == '[')
|
||||
{
|
||||
int idx;
|
||||
accept = source[1] != '^';
|
||||
idx = accept ? 1 : 2;
|
||||
List<RegexCharSet> list = [];
|
||||
ReadOnlySpan<char> seq = source.Slice(idx, source.Length - idx - 1);
|
||||
if (seq.IndexOf('-') == -1)
|
||||
{
|
||||
return [new RegexCharSet(seq.ToString(), CharSetType.Single, true)];
|
||||
SplitSet(single_char, seq, list);
|
||||
StringBuilder sb = new();
|
||||
foreach (char c in single_char) {
|
||||
_ = sb.Append(c);
|
||||
}
|
||||
list.Add(new(sb.ToString(), CharSetType.Single, true));
|
||||
} else
|
||||
{
|
||||
List<RegexCharSet> list = [];
|
||||
for (; seq.Length > 0; )
|
||||
{
|
||||
int pos = seq.IndexOf('-');
|
||||
if (pos == -1)
|
||||
{
|
||||
// has no range
|
||||
SplitSet(seq, list);
|
||||
SplitSet(single_char, seq, list);
|
||||
break;
|
||||
} else if (pos > 1)
|
||||
{
|
||||
// has other sequence before range
|
||||
SplitSet(seq[0..(pos - 1)], list);
|
||||
SplitSet(single_char, seq[0..(pos - 1)], list);
|
||||
}
|
||||
list.Add(new($"{seq[pos - 1]}{seq[pos + 1]}", CharSetType.Range, true));
|
||||
seq = seq[(pos + 2)..];
|
||||
}
|
||||
StringBuilder sb = new();
|
||||
foreach (char c in single_char) {
|
||||
_ = sb.Append(c);
|
||||
}
|
||||
list.Add(new(sb.ToString(), CharSetType.Single, true));
|
||||
return [.. list];
|
||||
}
|
||||
} else if (source[0] == '\\')
|
||||
@@ -293,6 +313,7 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
}
|
||||
|
||||
static void SplitSet(
|
||||
HashSet<char> single_char,
|
||||
ReadOnlySpan<char> seq,
|
||||
List<RegexCharSet> sets
|
||||
)
|
||||
@@ -310,19 +331,31 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
sets.Add(new RegexCharSet(singles.ToString(), CharSetType.Single, true));
|
||||
}
|
||||
bool accept = char.IsAsciiLetterUpper(remain[pos + 1]);
|
||||
RegexCharSet set_set = char.ToLower(remain[pos + 1], CultureInfo.InvariantCulture)
|
||||
switch
|
||||
|
||||
switch (char.ToLower(remain[pos + 1], CultureInfo.InvariantCulture))
|
||||
{
|
||||
's' => new("s", CharSetType.Set, accept),
|
||||
'w' => new("w", CharSetType.Set, accept),
|
||||
'd' => new("d", CharSetType.Set, accept),
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
sets.Add(set_set);
|
||||
case 's':
|
||||
sets.Add(new("s", CharSetType.Set, accept));
|
||||
break;
|
||||
case 'w':
|
||||
sets.Add(new("w", CharSetType.Set, accept));
|
||||
break;
|
||||
case 'd':
|
||||
sets.Add(new("d", CharSetType.Set, accept));
|
||||
break;
|
||||
case '['or'('or')'or']'or'\\'or'\"':
|
||||
_ = single_char.Add(remain[pos + 1]);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidCastException($"Unknown char or charset {remain[0..1]}");
|
||||
}
|
||||
remain = remain[(pos + 2)..];
|
||||
}
|
||||
if (remain.Length > 0) {
|
||||
sets.Add(new RegexCharSet(remain.ToString(), CharSetType.Single, true));
|
||||
if (remain.Length > 0)
|
||||
{
|
||||
foreach (char c in remain) {
|
||||
_ = single_char.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user