add more generate method of ALT node, add improve advise for gl source gen
This commit is contained in:
@@ -84,21 +84,21 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
/// <see langword="false" />.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <para> /// This method operates on a single <see cref="char" />, and therefore /// on
|
||||
/// a single UTF-16 code unit rather than on a complete Unicode scalar /// value.
|
||||
/// ///</para> <para> /// Characters in the Unicode Basic Multilingual Plane are
|
||||
/// classified /// normally. A supplementary-plane character is represented by a ///
|
||||
/// surrogate pair and is therefore presented to this method as two /// separate surrogate
|
||||
/// code units. Neither surrogate is independently /// treated as a word character. This
|
||||
/// follows the char-based behavior of /// the corresponding .NET Regex helper. ///</para>
|
||||
/// <para> /// For ASCII input, the Unicode-category lookup is avoided. In ASCII, /// the
|
||||
/// accepted set is exactly: /// <c> [A-Za-z0-9_] </c>. ///</para> <para> /// This method
|
||||
/// <para>/// This method operates on a single <see cref="char" />, and therefore /// on a
|
||||
/// single UTF-16 code unit rather than on a complete Unicode scalar /// value. ///
|
||||
/// </para> <para>/// Characters in the Unicode Basic Multilingual Plane are classified
|
||||
/// /// normally. A supplementary-plane character is represented by a /// surrogate pair
|
||||
/// and is therefore presented to this method as two /// separate surrogate code units.
|
||||
/// Neither surrogate is independently /// treated as a word character. This follows the
|
||||
/// char-based behavior of /// the corresponding .NET Regex helper. /// </para> <para>///
|
||||
/// For ASCII input, the Unicode-category lookup is avoided. In ASCII, /// the accepted
|
||||
/// set is exactly: /// <c> [A-Za-z0-9_] </c>. /// </para> <para>/// This method
|
||||
/// implements ordinary .NET <c> \w </c> semantics. It does /// not implement the ASCII-
|
||||
/// oriented behavior enabled by /// <c> RegexOptions.ECMAScript </c>. ///</para>
|
||||
/// oriented behavior enabled by /// <c> RegexOptions.ECMAScript </c>. /// </para>
|
||||
/// </remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected static bool IsCharWord(
|
||||
char value
|
||||
protected internal static bool IsCharWord(
|
||||
char value
|
||||
)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using StgSharp.RegularAnalysis.Abstraction;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
@@ -82,6 +83,36 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
return SyntaxFactory.Literal(value).Text;
|
||||
}
|
||||
|
||||
private static string GenerateCharSetExpression(
|
||||
RegexCharSet set
|
||||
)
|
||||
{
|
||||
string remainSpan = SourceGenContext._remain_span;
|
||||
string accept = set.Accept ? string.Empty : "!";
|
||||
switch (set.Type)
|
||||
{
|
||||
case RegexCharSetType.Single:
|
||||
return $"{accept}({FormatStringLiteral(set.Value)}.{nameof(MemoryExtensions.Contains)}({remainSpan}[0]))";
|
||||
case RegexCharSetType.Range:
|
||||
return $"{accept}({remainSpan}[0] >= {FormatCharLiteral(set.Value[0])} && {remainSpan}[0] <= {FormatCharLiteral(set.Value[1])})";
|
||||
case RegexCharSetType.Set:
|
||||
switch (set.Value[0])
|
||||
{
|
||||
case 's':
|
||||
return $"{accept}char.IsWhiteSpace({remainSpan}[0])";
|
||||
case 'w':
|
||||
return $"{accept}{nameof(TextRegex.IsCharWord)}({remainSpan}[0])";
|
||||
case 'd':
|
||||
return $"{accept}char.IsDigit({remainSpan}[0])";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto default;
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsNamedFind(
|
||||
RegexAstNode node
|
||||
)
|
||||
@@ -131,15 +162,37 @@ namespace StgSharp.RegularAnalysis.Text
|
||||
case RegexElementLabel.UNIT:
|
||||
_ = sc.AppendLine(@$"if({context.RemainSpan}[0] == {FormatCharLiteral(code[0])})")
|
||||
.AppendLine("{")
|
||||
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice(1);")
|
||||
.AppendLine($@"goto {exit_label};")
|
||||
.AppendLine("}");
|
||||
break;
|
||||
case RegexElementLabel.UNIT_SET:
|
||||
IReadOnlyList<RegexCharSet> split = current.PayloadAs<RegexCharSetPayload>()
|
||||
.Set;
|
||||
RegexCharSet first_set = split[0];
|
||||
for (int i = 1; i < split.Count - 1; i++) { }
|
||||
RegexCharSet last_set = split[^1];
|
||||
RegexCharSetPayload payload = current.PayloadAs<RegexCharSetPayload>();
|
||||
IReadOnlyList<RegexCharSet> split = payload.Set;
|
||||
bool accept = payload.Accept;
|
||||
RegexCharSet _set = split[0];
|
||||
_ = sc.AppendLine($"if({(accept ? string.Empty : "!(")} {GenerateCharSetExpression(_set)} ||");
|
||||
for (int i = 1; i < split.Count - 1; i++)
|
||||
{
|
||||
_set = split[i];
|
||||
_ = sc.AppendLine($" {GenerateCharSetExpression(_set)} ||");
|
||||
}
|
||||
_set = split[^1];
|
||||
_ = sc.AppendLine($" {GenerateCharSetExpression(_set)} ){(accept ? string.Empty : ')')}")
|
||||
.AppendLine("{")
|
||||
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice(1);")
|
||||
.AppendLine($@"goto {exit_label};")
|
||||
.AppendLine("}");
|
||||
break;
|
||||
case RegexElementLabel.UNIT_SPAN:
|
||||
_ = sc.AppendLine(@$"if({context.RemainSpan}.{MemoryExtensions.StartsWith}({FormatStringLiteral(code)}))")
|
||||
.AppendLine("{")
|
||||
.AppendLine($@"{context.RemainSpan} = {context.RemainSpan}.Slice(1);")
|
||||
.AppendLine($@"goto {exit_label};")
|
||||
.AppendLine("}");
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
|
||||
Reference in New Issue
Block a user