diff --git a/Directory.Build.props b/Directory.Build.props
index 696da8da..5a81fb36 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -82,7 +82,7 @@
$(SolutionRoot)bin\$(BuildRid)\
- $(SolutionRoot)bin\$(_OsTag)_$(_ArchTag)\
+ $(SolutionRoot)bin\$(BuildRid)\
@@ -117,4 +117,4 @@
$(DefineConstants);LINUX
-
\ No newline at end of file
+
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 3a5b6a4c..356949fe 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -66,36 +66,36 @@
- <_PackNative Include="$(SolutionRoot)bin\win_x64\$(NativeLibName).dll"
- Condition="Exists('$(SolutionRoot)bin\win_x64\$(NativeLibName).dll')"
+ <_PackNative Include="$(SolutionRoot)bin\win-x64\$(NativeLibName).dll"
+ Condition="Exists('$(SolutionRoot)bin\win-x64\$(NativeLibName).dll')"
PackagePath="runtimes\win-x64\native" Pack="true" />
- <_PackNative Include="$(SolutionRoot)bin\win_arm64\$(NativeLibName).dll"
- Condition="Exists('$(SolutionRoot)bin\win_arm64\$(NativeLibName).dll')"
+ <_PackNative Include="$(SolutionRoot)bin\win-arm64\$(NativeLibName).dll"
+ Condition="Exists('$(SolutionRoot)bin\win-arm64\$(NativeLibName).dll')"
PackagePath="runtimes\win-arm64\native" Pack="true" />
- <_PackNative Include="$(SolutionRoot)bin\linux_x64\lib$(NativeLibName).so"
- Condition="Exists('$(SolutionRoot)bin\linux_x64\lib$(NativeLibName).so')"
+ <_PackNative Include="$(SolutionRoot)bin\linux-x64\lib$(NativeLibName).so"
+ Condition="Exists('$(SolutionRoot)bin\linux-x64\lib$(NativeLibName).so')"
PackagePath="runtimes\linux-x64\native" Pack="true" />
- <_PackNative Include="$(SolutionRoot)bin\linux_arm64\lib$(NativeLibName).so"
- Condition="Exists('$(SolutionRoot)bin\linux_arm64\lib$(NativeLibName).so')"
+ <_PackNative Include="$(SolutionRoot)bin\linux-arm64\lib$(NativeLibName).so"
+ Condition="Exists('$(SolutionRoot)bin\linux-arm64\lib$(NativeLibName).so')"
PackagePath="runtimes\linux-arm64\native" Pack="true" />
- <_PackNative Include="$(SolutionRoot)bin\linux_ppc64le\lib$(NativeLibName).so"
- Condition="Exists('$(SolutionRoot)bin\linux_ppc64le\lib$(NativeLibName).so')"
+ <_PackNative Include="$(SolutionRoot)bin\linux-ppc64le\lib$(NativeLibName).so"
+ Condition="Exists('$(SolutionRoot)bin\linux-ppc64le\lib$(NativeLibName).so')"
PackagePath="runtimes\linux-ppc64le\native" Pack="true" />
- <_PackNative Include="$(SolutionRoot)bin\osx_x64\lib$(NativeLibName).dylib"
- Condition="Exists('$(SolutionRoot)bin\osx_x64\lib$(NativeLibName).dylib')"
+ <_PackNative Include="$(SolutionRoot)bin\osx-x64\lib$(NativeLibName).dylib"
+ Condition="Exists('$(SolutionRoot)bin\osx-x64\lib$(NativeLibName).dylib')"
PackagePath="runtimes\osx-x64\native" Pack="true" />
- <_PackNative Include="$(SolutionRoot)bin\osx_arm64\lib$(NativeLibName).dylib"
- Condition="Exists('$(SolutionRoot)bin\osx_arm64\lib$(NativeLibName).dylib')"
+ <_PackNative Include="$(SolutionRoot)bin\osx-arm64\lib$(NativeLibName).dylib"
+ Condition="Exists('$(SolutionRoot)bin\osx-arm64\lib$(NativeLibName).dylib')"
PackagePath="runtimes\osx-arm64\native" Pack="true" />
-
\ No newline at end of file
+
diff --git a/src/StgSharp.Native/CMakeLists.txt b/src/StgSharp.Native/CMakeLists.txt
index 56bf233f..7d10af82 100644
--- a/src/StgSharp.Native/CMakeLists.txt
+++ b/src/StgSharp.Native/CMakeLists.txt
@@ -52,7 +52,7 @@ else()
set(STGSHARP_ARCH_TAG ${SN_RESOLVED_ARCH_NAME})
endif()
-set(STGSHARP_BUILD_OUTPUT_DIR ${STGSHARP_SOLUTION_ROOT}/bin/${STGSHARP_OS_TAG}_${STGSHARP_ARCH_TAG})
+set(STGSHARP_BUILD_OUTPUT_DIR ${STGSHARP_SOLUTION_ROOT}/bin/${STGSHARP_OS_TAG}-${STGSHARP_ARCH_TAG})
# Compile-time intermediates (native PDB / .obj side files) live inside the CMake
# build tree (cmake_build/) so they get cleaned up with it.
set(STGSHARP_OBJECT_ROOT_DIR ${CMAKE_CURRENT_BINARY_DIR}/obj/${PROJECT_NAME})
diff --git a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IRGenerate.cs b/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IRGenerate.cs
index bd936483..2f070337 100644
--- a/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IRGenerate.cs
+++ b/src/StgSharp.RegularAnalysis/Text/RegexAnalyzer.IRGenerate.cs
@@ -28,7 +28,7 @@ namespace StgSharp.RegularAnalysis.Text
ref RegexInfo info
)
{
- List list = GenerateIRRecursion(tree.Root, 0, out int length).ToList();
+ List list = GenerateIRRecursion(tree.Root, 0, [], out int length).ToList();
info.MinPredictLength = length;
return list;
}
@@ -41,15 +41,17 @@ namespace StgSharp.RegularAnalysis.Text
int max,
bool isGreedy,
RegexAstNode right,
+ HashSet group_names,
out int minLength
)
{
bool is_operator = !RegexAstNode.IsNullOrEmpty(right) &&
- (right.Source.Flag & RegexElementLabel.OPERATOR) != 0;
+ (right.Source.Flag & RegexElementLabel.VAST_OPERATOR) != 0;
if (is_operator) // seq to be count is complex
{
- RegexIRGenerator right_ir = GenerateIRRecursion(right, curDepth + 1, out minLength);
+ RegexIRGenerator right_ir = GenerateIRRecursion(right, curDepth + 1, group_names,
+ out minLength);
_ = ir.EmitCountComplex(min, max, isGreedy, right_ir.Count);
_ = ir.EmitIRStream(right_ir);
} else
@@ -78,6 +80,7 @@ namespace StgSharp.RegularAnalysis.Text
private static RegexIRGenerator GenerateIRRecursion(
RegexAstNode node,
int depth,
+ HashSet group_names,
out int minLength
)
{
@@ -94,20 +97,28 @@ namespace StgSharp.RegularAnalysis.Text
Token token = node.Source;
+ HashSet gn = group_names ?? [];
+
switch (node.Source.Flag)
{
case RegexElementLabel.GROUP_BEGIN:
string group_source = token.Value;
// process group type
- bool is_group = group_source.Length == 1; // simple group: (pattern)
- string group_name =
- group_source.StartsWith(@"(?<", StringComparison.Ordinal) ?
- group_source[3..^1] : /* named group (?) */
- string.Empty; /* unnamed group (?:) */
+ bool has_name = group_source.StartsWith(@"(?<", StringComparison.Ordinal); // simple group: (pattern)
+ string group_name = has_name ?
+ group_source[3..^1] : /* named group (?) */
+ string.Empty; /* unnamed group (?:) */
+
+ if (has_name)
+ {
+ if (!gn.Add(group_name)) {
+ throw new InvalidOperationException($"Duplicate group name: {group_name}");
+ }
+ }
RegexIRGenerator groupIR = new();
- rightIR = GenerateIRRecursion(right, curDepth + 1, out minLength);
+ rightIR = GenerateIRRecursion(right, curDepth + 1, gn, out minLength);
_ = groupIR.EmitTry(rightIR.Count)
.EmitIRStream(rightIR)
.EmitCondition(2, 1)
@@ -123,15 +134,15 @@ namespace StgSharp.RegularAnalysis.Text
int length_once;
if (count_source_span[0] == '*') // infinite count
{
- EmitCount(curDepth, count_ir, 0, -1, isGreedy, seq, out _);
+ EmitCount(curDepth, count_ir, 0, -1, isGreedy, seq, gn, out _);
minLength = 0;
} else if (count_source_span[0] == '+') // at least one
{
- EmitCount(curDepth, count_ir, 1, -1, isGreedy, seq, out length_once);
+ EmitCount(curDepth, count_ir, 1, -1, isGreedy, seq, gn, out length_once);
minLength = length_once;
} else if (count_source_span[0] == '?') // zero or one
{
- EmitCount(curDepth, count_ir, 0, 1, isGreedy, seq, out _);
+ EmitCount(curDepth, count_ir, 0, 1, isGreedy, seq, gn, out _);
minLength = 0;
} else if (count_source_span[0] == '{') // zero or one, non-greedy
{
@@ -140,7 +151,7 @@ namespace StgSharp.RegularAnalysis.Text
{
if (int.TryParse(count_source[1..(isGreedy ? ^2 : ^1)], out int count))
{
- EmitCount(curDepth, count_ir, count, count, isGreedy, seq,
+ EmitCount(curDepth, count_ir, count, count, isGreedy, seq, gn,
out length_once);
minLength = length_once * count;
} else
@@ -152,7 +163,7 @@ namespace StgSharp.RegularAnalysis.Text
if (int.TryParse(count_source[1..comma_pos], out int min) &&
int.TryParse(count_source[(comma_pos + 1)..(isGreedy ? ^1 : ^2)], out int max))
{
- EmitCount(curDepth, count_ir, min, max, isGreedy, seq,
+ EmitCount(curDepth, count_ir, min, max, isGreedy, seq, gn,
out length_once);
minLength = length_once * min;
} else
@@ -195,7 +206,7 @@ namespace StgSharp.RegularAnalysis.Text
}
} else if ((left.Source.Flag & RegexElementLabel.VAST_OPERATOR) != 0)
{
- leftIR = GenerateIRRecursion(left, curDepth + 1, out left_length);
+ leftIR = GenerateIRRecursion(left, curDepth + 1, gn, out left_length);
_ = concat.EmitIRStream(leftIR);
}
@@ -225,7 +236,7 @@ namespace StgSharp.RegularAnalysis.Text
}
} else if ((right.Source.Flag & RegexElementLabel.VAST_OPERATOR) != 0)
{
- rightIR = GenerateIRRecursion(right, curDepth + 1, out right_length);
+ rightIR = GenerateIRRecursion(right, curDepth + 1, gn, out right_length);
_ = concat.EmitIRStream(rightIR);
}
minLength = left_length + right_length;
@@ -238,7 +249,8 @@ namespace StgSharp.RegularAnalysis.Text
int min_case_length = int.MaxValue;
while (!RegexAstNode.IsNullOrEmpty(cur_node))
{
- RegexIRGenerator _case = GenerateIRRecursion(cur_node, curDepth + 1, out int case_length);
+ RegexIRGenerator _case = GenerateIRRecursion(cur_node, curDepth + 1, gn,
+ out int case_length);
min_case_length = int.Min(case_length, min_case_length);
casesIRList.Add(_case);
ir_count += _case.Count;
diff --git a/src/StgSharp.RegularAnalysis/Text/RegexElementLabel.cs b/src/StgSharp.RegularAnalysis/Text/RegexElementLabel.cs
index 3d5676a4..e3246596 100644
--- a/src/StgSharp.RegularAnalysis/Text/RegexElementLabel.cs
+++ b/src/StgSharp.RegularAnalysis/Text/RegexElementLabel.cs
@@ -16,7 +16,7 @@ namespace StgSharp.RegularAnalysis.Text
[Flags]
public enum RegexElementLabel
{
-
+#pragma warning disable CA1707
NONE = 0,
UNIT = 1,
UNIT_SET = 2,
@@ -33,5 +33,6 @@ namespace StgSharp.RegularAnalysis.Text
ATOM_BEGIN = SEQUENCE | GROUP_BEGIN ,
ATOM_END = SEQUENCE | GROUP_END | COUNT,
+#pragma warning restore CA1707
}
}
diff --git a/src/StgSharp.RegularAnalysis/Text/RegexTokenParser.cs b/src/StgSharp.RegularAnalysis/Text/RegexTokenParser.cs
index dbe7eac3..c7c1181b 100644
--- a/src/StgSharp.RegularAnalysis/Text/RegexTokenParser.cs
+++ b/src/StgSharp.RegularAnalysis/Text/RegexTokenParser.cs
@@ -32,12 +32,10 @@ namespace StgSharp.RegularAnalysis.Text
}
if (Source.TryReadToken(out Token orig))
{
- if (((int)(orig.Flag & RegexElementLabel.ATOM_BEGIN) != 0) && ((int)_prev != 0))
+ if (((orig.Flag & RegexElementLabel.ATOM_BEGIN) != 0) && (_prev != 0))
{
- Token ret = new Token(string.Empty,
- orig.Line,
- orig.Column,
- RegexElementLabel.CONCAT);
+ Token ret = new(string.Empty, orig.Line, orig.Column,
+ RegexElementLabel.CONCAT);
_buffer.Enqueue(orig);
_prev = orig.Flag & RegexElementLabel.ATOM_END;
return ret;
diff --git a/src/StgSharp.RegularAnalysis/Text/RegexTokenUtil.cs b/src/StgSharp.RegularAnalysis/Text/RegexTokenUtil.cs
deleted file mode 100644
index c0049c1e..00000000
--- a/src/StgSharp.RegularAnalysis/Text/RegexTokenUtil.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// -----------------------------------------------------------------------------
-// file="RegexTokenUtil"
-// Project: StgSharp
-// Copyright (c) Nitload.
-// SPDX-License-Identifier: MIT
-// -----------------------------------------------------------------------------
-
-using StgSharp.RegularAnalysis.Abstraction;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace StgSharp.RegularAnalysis.Text
-{
- internal static class RegexTokenUtil
- {
-
- public static bool IsAccurateChar(
- this Token token
- )
- {
- return ((token.Flag & RegexElementLabel.UNIT) != 0 && token.Value.Length == 1) ||
- (token.Flag & RegexElementLabel.UNIT_SPAN) != 0;
- }
-
- }
-}
diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexAttribute.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexAttribute.cs
index e656ad7b..26b1fe9d 100644
--- a/src/StgSharp.RegularAnalysis/Text/TextRegexAttribute.cs
+++ b/src/StgSharp.RegularAnalysis/Text/TextRegexAttribute.cs
@@ -14,17 +14,12 @@ using System.Threading.Tasks;
namespace StgSharp.RegularAnalysis.Text
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
- public sealed class TextRegexAttribute : Attribute
+ public sealed class TextRegexAttribute(
+ string pattern
+ ) : Attribute
{
- public TextRegexAttribute(
- string pattern
- )
- {
- Pattern = pattern;
- }
-
- public string Pattern { get; }
+ public string Pattern { get; } = pattern;
}
}
diff --git a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs
index add9a863..c35f1c8c 100644
--- a/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs
+++ b/src/StgSharp.RegularAnalysis/Text/TextRegexSourceGen.GenClass.cs
@@ -8,6 +8,7 @@
using StgSharp.RegularAnalysis.Abstraction;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@@ -18,12 +19,16 @@ namespace StgSharp.RegularAnalysis.Text
internal partial class TextRegexSourceGen
{
+ private const string current_ptr = "current_ptr";
+ private const string orig_text = "text";
+
internal static SequenceEmitter GenerateSource(
TextRegexSource source
)
{
SequenceEmitter se = new();
List> sub_match_list = [];
+ VarNameGenerator ng = new();
RegexInfo info = source.Info;
List ir = source.IRs;
@@ -31,8 +36,6 @@ namespace StgSharp.RegularAnalysis.Text
RegexIR[] window = new RegexIR[8];
Span scan_win = window;
- const string current_ptr = "current_ptr";
-
_ = se.AppendLine($@"public override MatchResult Match({ROS_char} text)")//
.AppendLine(@"{");
@@ -49,9 +52,18 @@ namespace StgSharp.RegularAnalysis.Text
int index = 0;
do
{
+ int result;
+
int count = int.Min(8, ir_sp.Length - index);
ir_sp.Slice(index, count).CopyTo(scan_win);
- if (TryGenerateMatch(scan_win, se) > 0) { }
+ if (TryGenerateMatchSeq(scan_win, se, ng) > 0)
+ {
+ count++;
+ } else if (TryGenerateMatchSet(scan_win, se, ng) > 0)
+ {
+ count++;
+ } else { }
+ index += count;
} while (index < ir.Count);
foreach (SequenceEmitter _sub in sub_match_list)
@@ -63,27 +75,203 @@ namespace StgSharp.RegularAnalysis.Text
_ = se.Append(@"}");
return se;
- /**/
- int TryGenerateMatch(
- Span scan_win,
- SequenceEmitter sb
- )
- {
- if (scan_win[0] is not RegexMatchSeqIR seq) {
- return -1;
- }
- string pattern = seq.Pattern;
- int length = pattern.Length;
- _ = sb.AppendLine()
- .AppendLine($@"if(text[{current_ptr}..({current_ptr} + {length})] == {pattern})")
- .AppendLine($@"{{")
- .AppendLine($@"{current_ptr} += {length};")
- .AppendLine($@"}}");
-
- return 1;
- }
- /**/
}
+ #region var naming
+
+ private class VarNameGenerator
+ {
+
+ private int char_counter;
+
+ public string GenerateCharName()
+ {
+ string name = $"__char_{char_counter}";
+ char_counter++;
+ return name;
+ }
+
+ }
+
+ #endregion
+
+
+ #region sub generator
+
+ private static int TryGenerateMatchSeq(
+ Span scan_win,
+ SequenceEmitter se,
+ VarNameGenerator ng
+ )
+ {
+ if (scan_win[0] is not RegexMatchSeqIR seq) {
+ return -1;
+ }
+ string pattern = seq.Pattern;
+ int length = pattern.Length;
+ _ = se.AppendLine()
+ .AppendLine($@"if(text[{current_ptr}..({current_ptr} + {length})] == {pattern})")
+ .AppendLine($@"{{")
+ .AppendLine($@"{current_ptr} += {length};")
+ .AppendLine($@"}}");
+
+ return 1;
+ }
+
+ private static int TryGenerateMatchSet(
+ Span scan_win,
+ SequenceEmitter se,
+ VarNameGenerator ng
+ )
+ {
+ if (scan_win[0] is not RegexMatchSeqIR seq) {
+ return -1;
+ }
+ string pattern = seq.Pattern;
+ RegexCharSet[] set_pattern = FigureCharSetType(pattern);
+
+ string var_char = ng.GenerateCharName();
+ _ = se.AppendLine($@"// match charset of {pattern}")
+ .AppendLine($@"char {var_char} = {orig_text}[{current_ptr}];")
+ .AppendLine();
+
+ bool accept = set_pattern[0].Accept;
+
+ _ = se.AppendLine("if(");
+ RegexCharSet p = set_pattern[0];
+ string _case = GenerateCase(p);
+ string _case_begin = accept ? string.Empty : "!(";
+ _ = se.AppendLine($@"if ({_case_begin}{_case}||");
+
+ for (int i = 1; i < set_pattern.Length - 1; i++)
+ {
+ p = set_pattern[i];
+ _case = GenerateCase(p);
+ if (string.IsNullOrEmpty(_case))
+ {
+ continue;
+ }
+ _ = se.AppendLine($@" {_case} ||");
+ }
+
+ p = set_pattern[^1];
+ _case = GenerateCase(p);
+ string _case_end = accept ? string.Empty : ")";
+ _ = se.AppendLine($@"{_case}{_case_end})")
+ .AppendLine("{")
+ .AppendLine($@"{current_ptr} += 1;")
+ .AppendLine("}");
+
+ return 1;
+
+ string GenerateCase(
+ RegexCharSet c
+ )
+ {
+ return c.Type switch
+ {
+ // Handle single character
+ CharSetType.Single => $@"{var_char} == '{c.Value}'",
+
+ // Handle range of characters
+ CharSetType.Range => $@"({var_char} >= '{c.Value[0]}' && {var_char} <= '{c.Value[1]}')",
+
+ // Handle set of characters
+ CharSetType.Set => c.Value switch
+ {
+ "s" => $@"char.IsWhiteSpace({var_char})",
+ "w" => $@"char.IsLetterOrDigit({var_char}) || {var_char} == '_'",
+ "d" => $@"char.IsDigit({var_char})",
+ _ => throw new InvalidCastException(),
+ },
+ CharSetType.None => string.Empty,
+ _ => string.Empty,
+ };
+ }
+ }
+
+ #endregion
+
+ #region charset config
+
+ internal enum CharSetType
+ {
+
+ None,
+ Single,
+ Range,
+ Set
+
+ }
+
+ internal record struct RegexCharSet(
+ string Value,
+ CharSetType Type,
+ bool Accept
+ )
+ {
+
+ public override readonly string ToString()
+ {
+ return $"{{value:{Value}, type:{Type}, accept:{Accept}}}";
+ }
+
+ }
+
+ public static RegexCharSet[] FigureCharSetType(
+ ReadOnlySpan source
+ )
+ {
+ // range or single
+ bool accept;
+ if (source[0] == '[')
+ {
+ int idx;
+ accept = source[1] != '^';
+ idx = accept ? 1 : 2;
+ ReadOnlySpan seq = source.Slice(idx, source.Length - idx - 1);
+ if (seq.IndexOf('-') == -1)
+ {
+ return [new RegexCharSet(seq.ToString(), CharSetType.Single, accept)];
+ } else
+ {
+ List list = [];
+ for (; seq.Length > 0; )
+ {
+ int pos = seq.IndexOf('-');
+ if (pos == -1)
+ {
+ RegexCharSet single = new(seq.ToString(), CharSetType.Single, accept);
+ list.Add(single);
+ break;
+ } else
+ if (pos > 1) {
+ list.Add(new(seq[0..(pos - 1)].ToString(), CharSetType.Single, accept));
+ }
+ list.Add(new($"{seq[pos - 1]}{seq[pos + 1]}", CharSetType.Range, accept));
+ seq = seq[(pos + 2)..];
+ }
+ return [.. list];
+ }
+ } else if (source[0] == '\\')
+ {
+ // set
+ accept = char.IsAsciiLetterUpper(source[0]);
+ return char.ToLower(source[0], CultureInfo.InvariantCulture)
+ switch
+ {
+ 's' => [new("s", CharSetType.Set, accept)],
+ 'w' => [new("w", CharSetType.Set, accept)],
+ 'd' => [new("d", CharSetType.Set, accept)],
+ _ => throw new NotSupportedException()
+ };
+ } else
+ {
+ // unknown, throw
+ throw new InvalidCastException($"Unknown char set: {source}");
+ }
+ }
+
+ #endregion
}
}
diff --git a/test/StgSharpDebug/TestRegexAnalyse.cs b/test/StgSharpDebug/TestRegexAnalyse.cs
index 4527df11..fcfe3598 100644
--- a/test/StgSharpDebug/TestRegexAnalyse.cs
+++ b/test/StgSharpDebug/TestRegexAnalyse.cs
@@ -21,8 +21,8 @@ namespace StgSharp
{
private static string[] regexSource = [
- @"(a|b)(c|d)",
- /**/
+ @"(?123)(?123)",
+ /*
@"http|https|ftp|ftps",
@"abc[0-9]x|abc[0-9]y|abd[0-9]x|abd[0-9]y|xyz",
@"get_name|get_value|get_type|set_name|set_value|set_type",
@@ -52,11 +52,16 @@ namespace StgSharp
Console.WriteLine(ir[i].AsCommand(i));
}
/**/
+ /**/
Console.WriteLine("-----Optimized once-----");
List opt_ir = interpreterSource.IRs;
- for (int i = 0; i < opt_ir.Count; i++) {
- Console.WriteLine(opt_ir[i].AsCommand(i));
+ if (opt_ir is not null)
+ {
+ for (int i = 0; i < opt_ir.Count; i++) {
+ Console.WriteLine(opt_ir[i].AsCommand(i));
+ }
}
+ /**/
Console.WriteLine(interpreterSource.AnalyseException?.ToString() ?? "No error");
RegexInfo info = interpreterSource.Info;
Console.WriteLine("-----Regex Info-----");