Working on tree optimizer, char concat flatten ok, working on alt union

This commit is contained in:
Youmu Liu
2026-02-12 18:12:40 +08:00
parent 39dd32992d
commit 6c78373375
8 changed files with 285 additions and 70 deletions
@@ -40,7 +40,7 @@ namespace StgSharp.RegularAnalysis.TextRegex
internal class RegexAstNode : ISyntaxNode<RegexAstNode, RegexElementLabel>
{
private RegexAstNode _left, _right;
// private RegexAstNode _left, _right;
public RegexAstNode(
Token<RegexElementLabel> source
@@ -56,11 +56,11 @@ namespace StgSharp.RegularAnalysis.TextRegex
public static RegexAstNode Empty { get; }
= new EmptyRegexAstNode();
public RegexAstNode Previous { get; set; }
public virtual RegexAstNode Previous { get; set; }
public RegexAstNode Next { get; set; }
public virtual RegexAstNode Next { get; set; }
public RegexAstNode Parent { get; set; }
public virtual RegexAstNode Parent { get; set; }
public RegexAstNode Left
{
@@ -93,7 +93,7 @@ namespace StgSharp.RegularAnalysis.TextRegex
public string CodeConvertTemplate { get; }
public Token<RegexElementLabel> Source { get; }
public Token<RegexElementLabel> Source { get; private set; }
public void AppendNode(
RegexAstNode nextToken
@@ -123,8 +123,9 @@ namespace StgSharp.RegularAnalysis.TextRegex
RegexAstNode node
)
{
return node is null || node.Equals(Empty);
return node is null || node is EmptyRegexAstNode;
}
/**/
public void PrependNode(
RegexAstNode previousNode
@@ -144,39 +145,61 @@ namespace StgSharp.RegularAnalysis.TextRegex
} else if (Right == node) {
Right = Empty;
}
node.Parent = Empty;
}
public static bool TryMergeUnit(
RegexAstNode prev,
RegexAstNode next,
out RegexAstNode result
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static RegexAstNode NewEmptyNode(
)
{
Token<RegexElementLabel> pSource = prev.Source;
Token<RegexElementLabel> nSource = next.Source;
if (pSource.IsAccurateChar() &&
nSource.IsAccurateChar() &&
pSource.Column + pSource.Value.Length == nSource.Column)
{
// both are unit types and adjacent
// and are all accurate unit
Token<RegexElementLabel> newToken = new Token<RegexElementLabel>($"{pSource.Value}{nSource.Value}",
pSource.Line,
pSource.Column,
RegexElementLabel.UNIT_SPAN);
result = new RegexAstNode(newToken);
return true;
return new EmptyRegexAstNode();
}
/**/
internal void ReplaceBy(
RegexAstNode node
)
{
Source = node.Source;
Left = node.Left;
Right = node.Right;
if (IsNullOrEmpty(Left)) {
Left.Parent = this;
}
if (IsNullOrEmpty(Right)) {
Right.Parent = this;
}
Previous = node.Previous;
Next = node.Next;
RegexAstNode prev = Previous;
RegexAstNode next = Next;
if (!IsNullOrEmpty(prev)) {
prev.Next = this;
}
if (!IsNullOrEmpty(next)) {
next.Previous = this;
}
result = Empty;
return false;
}
private class EmptyRegexAstNode : RegexAstNode
private sealed class EmptyRegexAstNode : RegexAstNode
{
public EmptyRegexAstNode() : base(Token<RegexElementLabel>.Empty) { }
public override RegexAstNode Next
{
get;
set { field = Empty; }
}
public override RegexAstNode Previous
{
get;
set { field = Empty; }
}
}
}