add single ir generator methods
This commit is contained in:
@@ -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" />.
|
||||||
|
|||||||
Reference in New Issue
Block a user