add state nodes for regex state machine

This commit is contained in:
Youmu Liu
2026-01-27 18:40:44 +08:00
parent a36e6cbab4
commit 3881078770
13 changed files with 510 additions and 820 deletions
@@ -25,6 +25,7 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal;
using StgSharp.State;
using System;
@@ -44,9 +45,12 @@ namespace StgSharp.RegularAnalysis
private class RegularExpressionState : ISimpleStateMachine<RegularExpressionStateNode, int, RegularExpressionStateContext>
{
public ref readonly RegularExpressionStateNode this[
int label
] => throw new NotImplementedException();
private List<RegularExpressionStateNode> _nodes;
private RegularExpressionStateNode _currentState;
public RegularExpressionStateNode this[
int label
] => _nodes[label];
public ref readonly RegularExpressionStateNode GetCurrentStateNode()
{
@@ -65,22 +69,77 @@ namespace StgSharp.RegularAnalysis
throw new NotImplementedException();
}
}
#region node factory
private struct RegularExpressionStateNode : ISimpleStateMachineNode<int, RegularExpressionStateContext>
{
public ICollection<int> AvailableStateLabels => throw new NotImplementedException();
public SimpleStateMachineNodeTransition<int, RegularExpressionStateContext>
Transition => throw new NotImplementedException();
public bool TryTransaction(
RegularExpressionStateContext context,
out int label
public RegularExpressionCharNode AddChar(
char c
)
{
throw new NotImplementedException();
RegularExpressionCharNode node = new RegularExpressionCharNode(c);
int index = _nodes.Count;
_nodes.Add(node);
node.FailNodeIndex = index; // Point to self by default
return node;
}
public RegularExpressionCharsetNode AddCharset(
ReadOnlySpan<char> chars,
bool isNegate
)
{
RegularExpressionCharsetNode node = new RegularExpressionCharsetNode(chars, isNegate);
int index = _nodes.Count;
_nodes.Add(node);
node.FailNodeIndex = index; // Point to self by default
return node;
}
public RegularExpressionCounterNode AddCounter(
int minCount,
bool isEager
)
{
RegularExpressionCounterNode node = new RegularExpressionCounterNode(minCount, isEager);
int index = _nodes.Count;
_nodes.Add(node);
node.FailNodeIndex = index; // Point to self by default
return node;
}
#endregion
}
private abstract class RegularExpressionStateNode : SimpleStateMachineNode<RegularExpressionStateNode, int, RegularExpressionStateContext>
{
public int FailNodeIndex { get; set; }
public abstract NodeState Type { get; }
public override bool TryTransaction(
ReadOnlySpan<RegularExpressionStateNode> nodeSpan,
RegularExpressionStateContext context,
out int label
)
{
context.Position++;
int pos = context.Position;
if (pos < 0)
{
label = FailNodeIndex;
return true;
}
char c = context.CurrentCharSpan[pos];
foreach (int index in AvailableNodes)
{
if (nodeSpan[index].IsValidateFrom(this, context))
{
label = index;
return true;
}
}
label = FailNodeIndex;
return true;
}
}
@@ -90,7 +149,7 @@ namespace StgSharp.RegularAnalysis
public int Begin { get; set; }
public int Position { get; set; }
public int Position { get; set; } = -1;
public ReadOnlySpan<char> CurrentCharSpan => Source.AsSpan()[Begin..Position];