add single ir generator methods

This commit is contained in:
Youmu Liu
2026-08-06 18:05:06 +08:00
parent 068ad18998
commit b3e198dbaf
3 changed files with 48 additions and 28 deletions
@@ -88,8 +88,8 @@ namespace StgSharp.RegularAnalysis.Text
return -1; return -1;
} }
string group_name = pack.GroupName; string group_name = pack.GroupName;
string begin = sc.GroupBegin(group_name); string begin = sc.GetVarGroupBegin(group_name);
string end = sc.GroupEnd(group_name); string end = sc.GetVarGroupEnd(group_name);
_ = code.AppendLine(begin).AppendLine(end); _ = code.AppendLine(begin).AppendLine(end);
return 1; return 1;
} }
@@ -165,17 +165,21 @@ namespace StgSharp.RegularAnalysis.Text
string counter = sc.RequireNewCounter(); string counter = sc.RequireNewCounter();
// TODO cannot check real count outside the cycle // TODO cannot check real count outside the cycle
_ = code.AppendLine($@"int {counter} = 0;", // _ = code.AppendLine($@"int {counter} = 0;", //
@$"for(; {counter}<{leave}; {counter}++)", // @$"for(; {counter}<{leave}; {counter}++)", //
"{", // "{", //
@$"if({sc.InputSpan}[{sc.Position}..].StartWith({literal}))", // @$"if(!{sc.RemainingSpan}.StartWith({literal}))", //
"{", // "{", //
@$"{sc.Position}+={seq.Length};", // $@"break;", //
"}", // "}", //
"}", // "}", //
@$"if({counter}>{min})", // TODO match here @$"if({counter}>{min})", //
"{", // in case match
sc.MakeRemainOffset(counter), //
"}", //
$@"else", // $@"else", //
"}"); // TODO fail here "{", // TODO fail here
"}"); //
return 1; return 1;
} }
@@ -192,10 +196,13 @@ namespace StgSharp.RegularAnalysis.Text
} }
string seq = match_seq.Pattern; string seq = match_seq.Pattern;
string literal = FormatStringLiteral(seq); string literal = FormatStringLiteral(seq);
_ = code.AppendLine(@$"if({sc.InputSpan}[{sc.Position}..].StartWith({literal}))") _ = code.AppendLine(@$"if({sc.RemainingSpan}.StartWith({literal}))")
.AppendLine("{") .AppendLine("{")
.AppendLine($"{sc.StepResult} = true;") .AppendLine($"{sc.StepResult} = true;")
.AppendLine($@"{sc.Position} += {seq.Length};") .AppendLine(sc.MakeRemainOffset(seq.Length))
.AppendLine("}")
.AppendLine("else")
.AppendLine("{")//TODO fail here
.AppendLine("}"); .AppendLine("}");
return 1; return 1;
} }
@@ -237,7 +244,7 @@ namespace StgSharp.RegularAnalysis.Text
_case_code = GenLine(set, sc, ")"); _case_code = GenLine(set, sc, ")");
_ = code.AppendLine(_case_code) _ = code.AppendLine(_case_code)
.AppendLine("{") .AppendLine("{")
.AppendLine("-------------------------------------")// TODO case success .AppendLine(sc.MakeRemainOffset(1))// TODO case success
.AppendLine("}"); .AppendLine("}");
return 1; return 1;
} }
@@ -245,9 +252,11 @@ namespace StgSharp.RegularAnalysis.Text
private static string GenLine( private static string GenLine(
RegexCharSet set, RegexCharSet set,
SourceGenContext sc, SourceGenContext sc,
string end_of_line string end_of_line,
string symbol_of_offset = ""
) )
{ {
string offset = string.IsNullOrEmpty(symbol_of_offset) ? "0" : $"{symbol_of_offset}";
switch (set.Type) switch (set.Type)
{ {
case CharSetType.Single: case CharSetType.Single:
@@ -256,7 +265,7 @@ namespace StgSharp.RegularAnalysis.Text
{ {
// more than 8 different chars, using string match // more than 8 different chars, using string match
string literal = FormatStringLiteral(cases); string literal = FormatStringLiteral(cases);
return $@"{literal}.Contains({sc.InputSpan}[{sc.Position}]) {end_of_line}"; return $@"{literal}.Contains({sc.RemainingSpan}[{offset}]) {end_of_line}";
} else } else
{ {
StringBuilder sb = new(); StringBuilder sb = new();
@@ -265,10 +274,10 @@ namespace StgSharp.RegularAnalysis.Text
for (int j = 0; j < cases.Length - 1; j++) for (int j = 0; j < cases.Length - 1; j++)
{ {
literal = FormatCharLiteral(cases[j]); literal = FormatCharLiteral(cases[j]);
_ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.InputSpan}[{sc.Position}] == {literal} ||"); _ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.RemainingSpan}[{offset}] == {literal} ||");
} }
literal = FormatCharLiteral(cases[^1]); literal = FormatCharLiteral(cases[^1]);
_ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.InputSpan}[{sc.Position}] == {literal}") _ = sb.Append(CultureInfo.InvariantCulture, $@"{sc.RemainingSpan}[{offset}] == {literal}")
.Append(CultureInfo.InvariantCulture, @$") {end_of_line}"); .Append(CultureInfo.InvariantCulture, @$") {end_of_line}");
return sb.ToString(); return sb.ToString();
} }
@@ -276,15 +285,15 @@ namespace StgSharp.RegularAnalysis.Text
string rule = set.Value; string rule = set.Value;
char lo = rule[0]; char lo = rule[0];
char hi = rule[1]; char hi = rule[1];
return $@"({sc.InputSpan}[{sc.Position}] >= '{lo}' && {sc.InputSpan}[{sc.Position}] <= '{hi}') {end_of_line}"; return $@"({sc.RemainingSpan}[{offset}] >= '{lo}' && {sc.RemainingSpan}[{offset}] <= '{hi}') {end_of_line}";
case CharSetType.Set: case CharSetType.Set:
string accept_mark = set.Accept ? string.Empty : "!"; string accept_mark = set.Accept ? string.Empty : "!";
return set.Value switch return set.Value switch
{ {
"s" => $@"{accept_mark}char.IsWhiteSpace({sc.InputSpan}[{sc.Position}]) {end_of_line}", "s" => $@"{accept_mark}char.IsWhiteSpace({sc.RemainingSpan}[{offset})] {end_of_line}",
"d" => $@"{accept_mark}char.IsDigit({sc.InputSpan}[{sc.Position}]) {end_of_line}", "d" => $@"{accept_mark}char.IsDigit({sc.RemainingSpan}[{offset})] {end_of_line}",
"w" => $@"{accept_mark}IsCharWord({sc.InputSpan}[{sc.Position}]) {end_of_line}", "w" => $@"{accept_mark}IsCharWord({sc.RemainingSpan}[{offset})] {end_of_line}",
_ => string.Empty _ => string.Empty
}; };
case CharSetType.None: case CharSetType.None:
@@ -269,6 +269,7 @@ namespace StgSharp.RegularAnalysis.Text
_ = sb.Append(c); _ = sb.Append(c);
} }
list.Add(new(sb.ToString(), CharSetType.Single, true)); list.Add(new(sb.ToString(), CharSetType.Single, true));
return [.. list];
} else } else
{ {
for (; seq.Length > 0; ) for (; seq.Length > 0; )
@@ -343,7 +344,7 @@ namespace StgSharp.RegularAnalysis.Text
case 'd': case 'd':
sets.Add(new("d", CharSetType.Set, accept)); sets.Add(new("d", CharSetType.Set, accept));
break; break;
case '['or'('or')'or']'or'\\'or'\"': case '[' or '(' or ')' or ']' or '\\' or '\"':
_ = single_char.Add(remain[pos + 1]); _ = single_char.Add(remain[pos + 1]);
break; break;
default: default:
@@ -5,6 +5,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
using Microsoft.CodeAnalysis.Text;
using StgSharp.RegularAnalysis.Abstraction; using StgSharp.RegularAnalysis.Abstraction;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -29,11 +30,6 @@ namespace StgSharp.RegularAnalysis.Text
private sealed class SourceGenContext private sealed class SourceGenContext
{ {
/// <summary>
/// Active pointer. Indexes the next unconsumed element of the input.
/// </summary>
public const string _cursor = "__cur";
/// <summary> /// <summary>
/// Name of the match method parameter holding the input sequence. /// Name of the match method parameter holding the input sequence.
/// </summary> /// </summary>
@@ -54,7 +50,7 @@ namespace StgSharp.RegularAnalysis.Text
private readonly SortedSet<int> _lineSlots = []; private readonly SortedSet<int> _lineSlots = [];
private readonly SortedSet<int> _regionSlots = []; private readonly SortedSet<int> _regionSlots = [];
public string Position { get; } = _cursor; public string RemainingSpan { get; } = "__remaining_span";
public string InputSpan { get; } = _inputSpan; public string InputSpan { get; } = _inputSpan;
@@ -75,7 +71,7 @@ namespace StgSharp.RegularAnalysis.Text
return null!; return null!;
} }
_ = emitter.AppendLine($@"int {_cursor} = 0;") _ = emitter.AppendLine($@"{ROS_char} {RemainingSpan} = {_inputSpan};")
.AppendLine($@"bool {_stepResult} = true;"); .AppendLine($@"bool {_stepResult} = true;");
foreach (int region in _regionSlots) { foreach (int region in _regionSlots) {
@@ -95,14 +91,14 @@ namespace StgSharp.RegularAnalysis.Text
return emitter; return emitter;
} }
public string GroupBegin( public string GetVarGroupBegin(
string name string name
) )
{ {
return $"__g{ResolveGroup(name)}_begin"; return $"__g{ResolveGroup(name)}_begin";
} }
public string GroupEnd( public string GetVarGroupEnd(
string name string name
) )
{ {
@@ -133,6 +129,20 @@ namespace StgSharp.RegularAnalysis.Text
return $"__l{line}_ok"; return $"__l{line}_ok";
} }
public string MakeRemainOffset(
string offset_name
)
{
return @$"{RemainingSpan} = {RemainingSpan}[{offset_name}..];";
}
public string MakeRemainOffset(
int offset
)
{
return @$"{RemainingSpan} = {RemainingSpan}[{offset}..];";
}
/// <summary> /// <summary>
/// Records that some prefix observes the result of the instruction at line <paramref /// Records that some prefix observes the result of the instruction at line <paramref
/// name="line" />. /// name="line" />.