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
@@ -89,18 +89,14 @@ namespace StgSharp.RegularAnalysis.TextRegex
if ((token.Flag & RegexElementLabel.SEQUENCE) != 0)
{
// char or charset
Console.WriteLine($"Unit {token.Value}");
_stack.PushOperand(new RegexAstNode(token));
} else if ((token.Flag & RegexElementLabel.GROUP_BEGIN) != 0)
{
Console.WriteLine($"Group begin {token.Value}");
_stack.PushOperator(new RegexAstNode(token));
_stack.IncreaseDepth(0);
Console.WriteLine(/**/_stack.OperatorInDepthCount/**/);
} else if ((token.Flag & RegexElementLabel.GROUP_END) != 0)
{
// close all nodes here
Console.WriteLine($"Group end {token.Value}");
RegexAstNode op;
while (_stack.TryPopOperator(out op)) {
ProcessOperator(op);
@@ -120,8 +116,6 @@ namespace StgSharp.RegularAnalysis.TextRegex
}
} else if ((token.Flag & RegexElementLabel.OPERATOR) != 0)
{
Console.Write($"Operator {token.Value} with flag {token.Flag}, ");
Console.WriteLine(/**/_stack.OperatorInDepthCount/**/);
if (_stack.OperatorInDepthCount == 0)
{
// the first operator in stack
@@ -150,7 +144,6 @@ namespace StgSharp.RegularAnalysis.TextRegex
}
}
}
Console.WriteLine(1);
if (_stack.Depth == 1)
{
if (_stack.OperandInDepthCount != 1 || _stack.OperatorInDepthCount != 0)
@@ -164,7 +157,6 @@ namespace StgSharp.RegularAnalysis.TextRegex
_tree.Root = _stack.PopOperand();
return;
}
throw new InvalidOperationException("Invalid regular expression syntax.");
}
throw new InvalidOperationException("Invalid regular expression syntax.");
}
@@ -178,33 +170,37 @@ namespace StgSharp.RegularAnalysis.TextRegex
RegexAstNode current;
// phase1: ALT flatten
// phase2: CONCAT normalize
// phase2: then ALT union
// phase3: CONCAT normalize
int i = 0;
while (enumerator.MoveNext())
{
current = enumerator.Current;
RegexAstNode cur = current.Next;
if (current.EqualityTypeConvert == RegexElementLabel.ALT)
{
RegexAstNode union = FlattenAlt(current);
current.Right = union;
current.Left = RegexAstNode.Empty;
List<RegexAstNode> list = FlattenAlt(current);
RegexAstNode union = MergeAlt(list);
current.ReplaceBy(union);
} else if (current.EqualityTypeConvert == RegexElementLabel.CONCAT) {
RotateConcat(current);
}
}
// phase3: CONCAT merge
// phase4: CONCAT merge
enumerator.Reset();
while (enumerator.MoveNext())
{
// suppose all concat is now in normalized form,
// we can merge adjacent unit nodes into a single unit node with string value
current = enumerator.Current;
if (current.EqualityTypeConvert == RegexElementLabel.CONCAT) {
MergeConcat(current);
if (current.EqualityTypeConvert == RegexElementLabel.CONCAT)
{
if (MergeConcat(current)) {
enumerator.SkipOnce();
}
}
}
// phase4: ALT union
}
private void ProcessOperator(
@@ -244,8 +240,8 @@ namespace StgSharp.RegularAnalysis.TextRegex
if (_stack.TryPopOperand(out RegexAstNode? _1) &&
_stack.TryPopOperand(out RegexAstNode? _2))
{
op.Left = _1;
op.Right = _2;
op.Left = _2;
op.Right = _1;
_stack.PushOperand(op);
_tree.AddNode(op);
_tree.AddNode(_1);