diff --git a/StgSharp.RegularAnalysis/RegularExpression.cs b/StgSharp.RegularAnalysis/GroupIndex.cs similarity index 82% rename from StgSharp.RegularAnalysis/RegularExpression.cs rename to StgSharp.RegularAnalysis/GroupIndex.cs index 464a0167..f77a6c7c 100644 --- a/StgSharp.RegularAnalysis/RegularExpression.cs +++ b/StgSharp.RegularAnalysis/GroupIndex.cs @@ -1,6 +1,6 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="RegularExpression" +// file="GroupIndex" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -25,19 +25,26 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- +using System.Runtime.InteropServices; + namespace StgSharp.RegularAnalysis { - public partial class RegularExpression + public record struct GroupIndex { - private class GroupIndex + public GroupIndex( + int index, + string name + ) { - - public int Index { get; set; } - - public string Name { get; set; } - + Index = index; + Name = name; } + public int Index { get; internal set; } + + public string Name { get; internal set; } + } } + diff --git a/StgSharp.RegularAnalysis/RegularExpression.StateMachine.cs b/StgSharp.RegularAnalysis/RegularExpression.StateMachine.cs deleted file mode 100644 index f63c5228..00000000 --- a/StgSharp.RegularAnalysis/RegularExpression.StateMachine.cs +++ /dev/null @@ -1,170 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="RegularExpression.StateMachine" -// 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.Internal; -using StgSharp.State; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using System.Threading.Tasks; - -namespace StgSharp.RegularAnalysis -{ - public partial class RegularExpression - { - - private readonly RegularExpressionState _state; - - private class RegularExpressionState : ISimpleStateMachine - { - - private List _nodes; - private RegularExpressionStateNode _currentState; - - public RegularExpressionStateNode this[ - int label - ] => _nodes[label]; - - public ref readonly RegularExpressionStateNode GetCurrentStateNode() - { - throw new NotImplementedException(); - } - - public void Reset() - { - throw new NotImplementedException(); - } - - public bool TryMoveNext( - RegularExpressionStateContext ctx - ) - { - throw new NotImplementedException(); - } - - #region node factory - - public RegularExpressionCharNode AddChar( - char c - ) - { - 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 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 (RegularExpressionLeftBoarderNode left) AddBoarder(string groupName, int groupIndex) - { - RegularExpressionLeftBoarderNode leftNode = new RegularExpressionLeftBoarderNode(new GroupIndex(groupName, groupIndex)); - int leftIndex = _nodes.Count; - _nodes.Add(leftNode); - leftNode.FailNodeIndex = leftIndex; // Point to self by default - return (left: leftNode); - } - - 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 - { - - public int FailNodeIndex { get; set; } - - public abstract NodeState Type { get; } - - public override bool TryTransaction( - ReadOnlySpan 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; - } - - } - - private class RegularExpressionStateContext : StateContext - { - - public int Begin { get; set; } - - public int Position { get; set; } = -1; - - public ReadOnlySpan CurrentCharSpan => Source.AsSpan()[Begin..Position]; - - public string Source { get; init; } - - } - - } -} diff --git a/StgSharp.RegularAnalysis/RegularExpression.Node.Count.cs b/StgSharp.RegularAnalysis/RegulartMachine/Node.Boarder.cs similarity index 54% rename from StgSharp.RegularAnalysis/RegularExpression.Node.Count.cs rename to StgSharp.RegularAnalysis/RegulartMachine/Node.Boarder.cs index ffccf825..3b8cdf5d 100644 --- a/StgSharp.RegularAnalysis/RegularExpression.Node.Count.cs +++ b/StgSharp.RegularAnalysis/RegulartMachine/Node.Boarder.cs @@ -1,6 +1,6 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="RegularExpression.Node.Count" +// file="Node.Boarder" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -33,45 +33,64 @@ using System.Threading.Tasks; namespace StgSharp.RegularAnalysis { - public partial class RegularExpression + internal class RegularExpressionLeftBoarderNode : RegularStateNode { - private class RegularExpressionCounterNode : RegularExpressionStateNode + public RegularExpressionLeftBoarderNode( + int index, + string name + ) { - - private readonly int _maxCount; - private readonly int _minCount; - - public RegularExpressionCounterNode( - int minCount, - bool isEager - ) + Boarder = new GroupIndex { - _minCount = minCount; - IsEager = isEager; - } + Index = index, + Name = name + }; + } - public bool IsEager { get; init; } + public event EventHandler OnBoarderEntered; - public int Count { get; private set; } + public GroupIndex Boarder { get; private set; } - public override NodeState Type => NodeState.COUNT; + public override NodeType Type => NodeType.LEFT_BOARDER; - public RegularExpressionStateNode LoopBack { get; set; } + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + return true; + } - public override bool IsValidateFrom( - RegularExpressionStateNode former, - RegularExpressionStateContext context - ) + } + + internal class RegularExpressionRightBoarderNode : RegularStateNode + { + + public RegularExpressionRightBoarderNode( + int index, + string name + ) + { + Boarder = new GroupIndex { - return true; - } + Index = index, + Name = name + }; + } - public void Reset() - { - Count = 0; - } + public event EventHandler OnBoarderEntered; + public GroupIndex Boarder { get; private set; } + + public override NodeType Type => NodeType.RIGHT_BOARDER; + + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + return true; } } diff --git a/StgSharp.RegularAnalysis/RegularExpression.Node.Char.cs b/StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs similarity index 83% rename from StgSharp.RegularAnalysis/RegularExpression.Node.Char.cs rename to StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs index cfceee7c..ee078eed 100644 --- a/StgSharp.RegularAnalysis/RegularExpression.Node.Char.cs +++ b/StgSharp.RegularAnalysis/RegulartMachine/Node.Char.cs @@ -35,10 +35,7 @@ using System.Threading.Tasks; namespace StgSharp.RegularAnalysis { - public partial class RegularExpression - { - - private class RegularExpressionCharNode : RegularExpressionStateNode + internal class RegularExpressionCharNode : RegularStateNode { private char _char; @@ -50,11 +47,11 @@ namespace StgSharp.RegularAnalysis _char = c; } - public override NodeState Type => NodeState.CHAR; + public override NodeType Type => NodeType.CHAR; public override bool IsValidateFrom( - RegularExpressionStateNode former, - RegularExpressionStateContext context + RegularStateNode former, + RegularContext context ) { int pos = context.Position; @@ -64,7 +61,7 @@ namespace StgSharp.RegularAnalysis } - private class RegularExpressionCharsetNode : RegularExpressionStateNode + internal class RegularExpressionCharsetNode : RegularStateNode { private bool _isNegated; @@ -91,11 +88,11 @@ namespace StgSharp.RegularAnalysis _isNegated = isNegated; } - public override NodeState Type => NodeState.CHARSET; + public override NodeType Type => NodeType.CHARSET; public override bool IsValidateFrom( - RegularExpressionStateNode former, - RegularExpressionStateContext context + RegularStateNode former, + RegularContext context ) { int pos = context.Position; @@ -104,7 +101,7 @@ namespace StgSharp.RegularAnalysis return _isNegated ? !contains : contains; } - } + } } diff --git a/StgSharp.RegularAnalysis/RegularExpression.Node.Boarder.cs b/StgSharp.RegularAnalysis/RegulartMachine/Node.Count.cs similarity index 64% rename from StgSharp.RegularAnalysis/RegularExpression.Node.Boarder.cs rename to StgSharp.RegularAnalysis/RegulartMachine/Node.Count.cs index f49909a1..b1b0792e 100644 --- a/StgSharp.RegularAnalysis/RegularExpression.Node.Boarder.cs +++ b/StgSharp.RegularAnalysis/RegulartMachine/Node.Count.cs @@ -1,6 +1,6 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="RegularExpression.Node.Boarder" +// file="Node.Count" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -33,38 +33,40 @@ using System.Threading.Tasks; namespace StgSharp.RegularAnalysis { - public partial class RegularExpression + internal class RegularExpressionCounterNode : RegularStateNode { - private class RegularExpressionLeftBoarderNode : RegularExpressionStateNode + private readonly int _maxCount; + private readonly int _minCount; + + public RegularExpressionCounterNode( + int minCount, + bool isEager + ) { + _minCount = minCount; + IsEager = isEager; + } - public RegularExpressionLeftBoarderNode( - int index, - string name - ) - { - Boarder = new GroupIndex - { - Index = index, - Name = name - }; - } + public bool IsEager { get; init; } - public event EventHandler OnBoarderEntered; + public int Count { get; private set; } - public GroupIndex Boarder { get; private set; } + public override NodeType Type => NodeType.COUNT; - public override NodeState Type => throw new NotImplementedException(); + public RegularStateNode LoopBack { get; set; } - public override bool IsValidateFrom( - RegularExpressionStateNode former, - RegularExpressionStateContext context - ) - { - return true; - } + public override bool IsValidateFrom( + RegularStateNode former, + RegularContext context + ) + { + return true; + } + public void Reset() + { + Count = 0; } } diff --git a/StgSharp.RegularAnalysis/RegularExpression.NodeState.cs b/StgSharp.RegularAnalysis/RegulartMachine/NodeType.cs similarity index 70% rename from StgSharp.RegularAnalysis/RegularExpression.NodeState.cs rename to StgSharp.RegularAnalysis/RegulartMachine/NodeType.cs index f5253e28..f0591b1d 100644 --- a/StgSharp.RegularAnalysis/RegularExpression.NodeState.cs +++ b/StgSharp.RegularAnalysis/RegulartMachine/NodeType.cs @@ -33,31 +33,30 @@ using System.Threading.Tasks; namespace StgSharp.RegularAnalysis { - public partial class RegularExpression + internal enum NodeType { - private enum NodeState - { + // single unicode character: a、B、1、@、汉字 etc. + CHAR, - // single unicode character: a、b、1、@、汉字 etc. - CHAR, + // collections of finate characters: [abc]、[^abc]、\d、\w、\s、\D、\W、\S etc. + CHARSET, - // collections of finate characters: [abc]、[^abc]、\d、\w、\s、\D、\W、\S etc. - CHARSET, + // increase count of a counter, half function of *+? quantifiers + COUNT, - // increase count of a counter, half function of *+? quantifiers - COUNT, + // left boarder of a sub sequnce, usually begin of match group or lookaround + LEFT_BOARDER, - // left boarder of a sub sequnce, usually begin of match group or lookaround - LEFT_BOARDER, + // right boarder of a sub sequnce, usually end of match group or lookaround + RIGHT_BOARDER, - // right boarder of a sub sequnce, usually end of match group or lookaround - RIGHT_BOARDER, + // zero length char or structure + EPSILON, - // zero length char or structure - EPSILON - - } + // more than one cases to match, like alter|nation + BRANCH } } + \ No newline at end of file diff --git a/StgSharp.RegularAnalysis/RegulartMachine/StateMachine.cs b/StgSharp.RegularAnalysis/RegulartMachine/StateMachine.cs new file mode 100644 index 00000000..baa2ef0e --- /dev/null +++ b/StgSharp.RegularAnalysis/RegulartMachine/StateMachine.cs @@ -0,0 +1,170 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="StateMachine" +// 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.Internal; +using StgSharp.State; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis +{ + internal class RegularExpressionState : ISimpleStateMachine + { + + private List _nodes; + private RegularStateNode _currentState; + + public RegularStateNode this[ + int label + ] => _nodes[label]; + + public ref readonly RegularStateNode GetCurrentStateNode() + { + throw new NotImplementedException(); + } + + public void Reset() + { + throw new NotImplementedException(); + } + + public bool TryMoveNext( + RegularContext ctx + ) + { + throw new NotImplementedException(); + } + + #region node factory + + public RegularExpressionCharNode AddChar( + char c + ) + { + 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 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 (RegularExpressionLeftBoarderNode left,RegularExpressionRightBoarderNode right) AddBoarder( + string groupName, + int groupIndex + ) + { + RegularExpressionLeftBoarderNode leftNode = new RegularExpressionLeftBoarderNode(groupIndex, groupName); + int leftIndex = _nodes.Count; + _nodes.Add(leftNode); + leftNode.FailNodeIndex = leftIndex; // Point to self by default + RegularExpressionRightBoarderNode rightNode = new RegularExpressionRightBoarderNode(groupIndex, groupName); + int rightIndex = _nodes.Count; + _nodes.Add(rightNode); + rightNode.FailNodeIndex = rightIndex; // Point to self by default + return (left: leftNode,right:rightNode); + } + + 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 + } + + 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 + { + + public int Begin { get; set; } + + public int Position { get; set; } = -1; + + public ReadOnlySpan CurrentCharSpan => Source.AsSpan()[Begin..Position]; + + public string Source { get; init; } + + } +}