From fe0e4ad7a48eab92b0a3bb55c0c44c01d98ce118 Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Mon, 2 Feb 2026 18:11:46 +0800 Subject: [PATCH] all node type are defined --- .../Node.Boarder.cs | 0 .../RegularMachine/Node.Branch.cs | 95 +++++++++ .../RegularMachine/Node.Char.cs | 196 ++++++++++++++++++ .../Node.Count.cs | 0 .../RegularMachine/Node.Sequence.cs | 37 ++++ .../RegularMachine/Node.cs | 70 +++++++ .../NodeType.cs | 5 +- .../StateMachine.cs | 39 +--- .../RegulartMachine/Node.Char.cs | 93 --------- 9 files changed, 405 insertions(+), 130 deletions(-) rename StgSharp.RegularAnalysis/{RegulartMachine => RegularMachine}/Node.Boarder.cs (100%) create mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs create mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Char.cs rename StgSharp.RegularAnalysis/{RegulartMachine => RegularMachine}/Node.Count.cs (100%) create mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs create mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.cs rename StgSharp.RegularAnalysis/{RegulartMachine => RegularMachine}/NodeType.cs (94%) rename StgSharp.RegularAnalysis/{RegulartMachine => RegularMachine}/StateMachine.cs (82%) delete mode 100644 StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs diff --git a/StgSharp.RegularAnalysis/RegulartMachine/Node.Boarder.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Boarder.cs similarity index 100% rename from StgSharp.RegularAnalysis/RegulartMachine/Node.Boarder.cs rename to StgSharp.RegularAnalysis/RegularMachine/Node.Boarder.cs diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs new file mode 100644 index 00000000..bcb17ee4 --- /dev/null +++ b/StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="Node.Branch" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.MVVM; +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis +{ + internal class RegularBranchNode : RegularStateNode + { + + private int _lastBranch; + + private List _result; + + public override NodeType Type => NodeType.BRANCH; + + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + return true; + } + + public override bool TryTransaction( + ReadOnlySpan nodeSpan, + RegularContext context, + out int label + ) + { + int pos = context.LastBranch.Peek(); + if (AvailableNodes.Length > _lastBranch) + { + // return measure result + label = 0; + return true; + } + label = FailNodeIndex; + return false; + } + + } + + internal struct BranchMeasureResult + { + + internal BranchMeasureResult( + bool match, + int size + ) + { + IsMatch = match; + + Length = size; + } + + public bool IsMatch { get; init; } + + public static BranchMeasureResult Fail { get; } = new BranchMeasureResult(); + + public int Length { get; init; } + + } +} diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.Char.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Char.cs new file mode 100644 index 00000000..57460392 --- /dev/null +++ b/StgSharp.RegularAnalysis/RegularMachine/Node.Char.cs @@ -0,0 +1,196 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="Node.Char" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.State; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis +{ + internal enum EpsilonKind + { + + Always, + Begin, + End, + LineBegin, + LineEnd, + WordBoundary, + NonWordBoundary + + } + + internal class RegularExpressionEpsilonNode : RegularStateNode + { + + public RegularExpressionEpsilonNode( + EpsilonKind kind = EpsilonKind.Always + ) + { + Kind = kind; + } + + public EpsilonKind Kind { get; } + + public override NodeType Type => NodeType.EPSILON; + + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + int pos = context.Position; + int len = context.Source?.Length ?? 0; + + bool PrevIsWord() + { + if (pos - 1 < 0 || pos - 1 >= len) { + return false; + } + + char c = context.Source[pos - 1]; + return char.IsLetterOrDigit(c) || c == '_'; + } + + bool NextIsWord() + { + if (pos < 0 || pos >= len) { + return false; + } + + char c = context.Source[pos]; + return char.IsLetterOrDigit(c) || c == '_'; + } + + switch (Kind) + { + case EpsilonKind.Always: + return true; + case EpsilonKind.Begin: + return pos == context.Begin; + case EpsilonKind.End: + return pos == len; + case EpsilonKind.LineBegin: + if (pos == 0) { + return true; + } + + if (pos - 1 < 0 || pos - 1 >= len) { + return false; + } + + return context.Source[pos - 1] == '\n' || context.Source[pos - 1] == '\r'; + case EpsilonKind.LineEnd: + if (pos == len) { + return true; + } + + if (pos < 0 || pos >= len) { + return false; + } + + return context.Source[pos] == '\n' || context.Source[pos] == '\r'; + case EpsilonKind.WordBoundary: + return PrevIsWord() != NextIsWord(); + case EpsilonKind.NonWordBoundary: + return PrevIsWord() == NextIsWord(); + default: + return false; + } + } + + } + + internal class RegularExpressionCharNode : RegularStateNode + { + + private char _char; + + public RegularExpressionCharNode( + char c + ) + { + _char = c; + } + + public override NodeType Type => NodeType.CHAR; + + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + int pos = context.Position; + char c = context.CurrentCharSpan[pos + 1]; + return c == _char; + } + + } + + internal class RegularExpressionCharsetNode : RegularStateNode + { + + private bool _isNegated; + private HashSet _charset; + + public RegularExpressionCharsetNode( + IEnumerable charset, + bool isNegated = false + ) + { + _charset = new(charset); + _isNegated = isNegated; + } + + public RegularExpressionCharsetNode( + ReadOnlySpan charset, + bool isNegated = false + ) + { + _charset = new(charset.Length); + _isNegated = isNegated; + } + + public override NodeType Type => NodeType.CHARSET; + + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + int pos = context.Position; + char c = context.CurrentCharSpan[pos + 1]; + bool contains = _charset.Contains(c); + return _isNegated ? !contains : contains; + } + + } +} diff --git a/StgSharp.RegularAnalysis/RegulartMachine/Node.Count.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Count.cs similarity index 100% rename from StgSharp.RegularAnalysis/RegulartMachine/Node.Count.cs rename to StgSharp.RegularAnalysis/RegularMachine/Node.Count.cs diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs new file mode 100644 index 00000000..41c45c1c --- /dev/null +++ b/StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis +{ + internal class RegularSequenceNode : RegularStateNode + { + + private string _sequence; + + public override NodeType Type => NodeType.SEQUENCE; + + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + return true; + } + + public override bool TryTransaction( + ReadOnlySpan nodeSpan, + RegularContext context, + out int label + ) + { + int pos = context.Position + 1; + if (true) { } + label = -1; + return false; + } + + } +} diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.cs new file mode 100644 index 00000000..a2a6c71c --- /dev/null +++ b/StgSharp.RegularAnalysis/RegularMachine/Node.cs @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="Node" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.State; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis +{ + internal abstract class RegularStateNode : SimpleStateMachineNode + { + + public int FailNodeIndex { get; set; } + + public abstract NodeType Type { get; } + + public override bool TryTransaction( + ReadOnlySpan nodeSpan, + RegularContext context, + out int label + ) + { + int pos = context.Position; + if (pos < 0) + { + label = FailNodeIndex; + return false; + } + char c = context.CurrentCharSpan[pos]; + foreach (int index in AvailableNodes) + { + if (nodeSpan[index].IsValidateFrom(this, context)) + { + label = index; + return true; + } + } + label = FailNodeIndex; + return false; + } + + } +} diff --git a/StgSharp.RegularAnalysis/RegulartMachine/NodeType.cs b/StgSharp.RegularAnalysis/RegularMachine/NodeType.cs similarity index 94% rename from StgSharp.RegularAnalysis/RegulartMachine/NodeType.cs rename to StgSharp.RegularAnalysis/RegularMachine/NodeType.cs index f0591b1d..405a59a3 100644 --- a/StgSharp.RegularAnalysis/RegulartMachine/NodeType.cs +++ b/StgSharp.RegularAnalysis/RegularMachine/NodeType.cs @@ -55,7 +55,10 @@ namespace StgSharp.RegularAnalysis EPSILON, // more than one cases to match, like alter|nation - BRANCH + BRANCH, + + // a sequence of nodes to match in order, each char should be fully defined but not charset + SEQUENCE } } diff --git a/StgSharp.RegularAnalysis/RegulartMachine/StateMachine.cs b/StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs similarity index 82% rename from StgSharp.RegularAnalysis/RegulartMachine/StateMachine.cs rename to StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs index baa2ef0e..62046ca5 100644 --- a/StgSharp.RegularAnalysis/RegulartMachine/StateMachine.cs +++ b/StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs @@ -44,7 +44,7 @@ namespace StgSharp.RegularAnalysis private RegularStateNode _currentState; public RegularStateNode this[ - int label + int label ] => _nodes[label]; public ref readonly RegularStateNode GetCurrentStateNode() @@ -120,41 +120,6 @@ namespace StgSharp.RegularAnalysis #endregion } - internal abstract class RegularStateNode : SimpleStateMachineNode - { - - public int FailNodeIndex { get; set; } - - public abstract NodeType Type { get; } - - public override bool TryTransaction( - ReadOnlySpan nodeSpan, - RegularContext 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; - } - - } - internal class RegularContext : StateContext { @@ -166,5 +131,7 @@ namespace StgSharp.RegularAnalysis public string Source { get; init; } + internal Stack LastBranch { get; } = new(); + } } diff --git a/StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs b/StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs deleted file mode 100644 index e78a3826..00000000 --- a/StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs +++ /dev/null @@ -1,93 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Node.Char" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.State; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.RegularAnalysis -{ - internal class RegularExpressionEpsilonNode : RegularStateNode - { - } - - - internal class RegularExpressionCharNode : RegularStateNode - { - - private char _char; - - public RegularExpressionCharNode(char c) - { - _char = c; - } - - public override NodeType Type => NodeType.CHAR; - - public override bool IsValidateFrom(RegularStateNode former, RegularContext context) - { - int pos = context.Position; - char c = context.CurrentCharSpan[pos + 1]; - return c == _char; - } - - } - - internal class RegularExpressionCharsetNode : RegularStateNode - { - - private bool _isNegated; - private HashSet _charset; - - public RegularExpressionCharsetNode(IEnumerable charset, bool isNegated = false) - { - _charset = new(charset); - _isNegated = isNegated; - } - - public RegularExpressionCharsetNode(ReadOnlySpan charset, bool isNegated = false) - { - _charset = new(charset.Length); - _isNegated = isNegated; - } - - public override NodeType Type => NodeType.CHARSET; - - public override bool IsValidateFrom(RegularStateNode former, RegularContext context) - { - int pos = context.Position; - char c = context.CurrentCharSpan[pos + 1]; - bool contains = _charset.Contains(c); - return _isNegated ? !contains : contains; - } - - } -}