From 861b50575a43e56d654e481f8a6f0eb171f8c4cc Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Mon, 15 Jun 2026 18:08:14 +0800 Subject: [PATCH] ngra string regex use ir as jit engine as well --- .../Numeric/Linear/MatrixCompute.Single.cs | 3 +- .../Numeric/Linear/MatrixStorage.cs | 2 +- .../Numeric/Runtime/MatrixParallel.Publish.cs | 3 +- .../Numeric/Runtime/MatrixParallelQueue.cs | 6 +- .../Abstraction/AbstractSyntaxTree.cs | 26 +- StgSharp.RegularAnalysis/Abstraction/Token.cs | 4 +- .../RegularMachine/Node.Boarder.cs | 97 ------- .../RegularMachine/Node.Branch.cs | 107 -------- .../RegularMachine/Node.Char.cs | 196 -------------- .../RegularMachine/Node.Sequence.cs | 27 -- .../RegularMachine/Node.cs | 70 ----- .../RegularMachine/NodeType.cs | 65 ----- .../RegularMachine/StateMachine.cs | 138 ---------- .../TextRegex/RegexAstNode.cs | 7 - StgSharp.RegularAnalysis/TextRegex/RegexIR.cs | 242 ++++++++++++++++++ .../RegexInterpreter.IRGenerate.cs} | 43 +--- .../TextRegex/RegexInterpreter.Optimize.cs | 14 +- .../TextRegex/RegexInterpreter.cs | 5 +- .../TextRegex/RegexTokenParser.cs | 3 +- .../TextRegex/RegexTokenReader.cs | 47 ++-- StgSharpDebug/Program.cs | 5 +- StgSharpDebug/TestRegexAnalyse.cs | 10 +- future/ngra-regex-ir.md | 27 ++ 23 files changed, 352 insertions(+), 795 deletions(-) delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Boarder.cs delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Char.cs delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/Node.cs delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/NodeType.cs delete mode 100644 StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs create mode 100644 StgSharp.RegularAnalysis/TextRegex/RegexIR.cs rename StgSharp.RegularAnalysis/{RegularMachine/Node.Count.cs => TextRegex/RegexInterpreter.IRGenerate.cs} (65%) create mode 100644 future/ngra-regex-ir.md diff --git a/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Single.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Single.cs index ac849560..f0a48033 100644 --- a/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Single.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Single.cs @@ -66,13 +66,14 @@ namespace StgSharp.Mathematics.Numeric mat_mk[f32.IntrinsicNode]. Get(MatrixIntrinsicHandle.Add); MatrixParallelTask* t = stackalloc MatrixParallelTask[1]; - + /* t->Mat1 = (MatrixKernel*)leftPtr; t->Mat2 = (MatrixKernel*)rightPtr; t->Mat3 = (MatrixKernel*)ansPtr; t->ElementType = f32; t->ComputeHandle = MatrixIntrinsicHandle.Add; t->Scalar.Data(0) = count; + /**/ SequentialOperation(t, count); } diff --git a/StgSharp.Mathematics/Numeric/Linear/MatrixStorage.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixStorage.cs index 0257ea6a..30130a40 100644 --- a/StgSharp.Mathematics/Numeric/Linear/MatrixStorage.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixStorage.cs @@ -62,7 +62,7 @@ namespace StgSharp.Mathematics.Numeric internal readonly Tlsf _allocator = allocator; - protected internal override unsafe T* BufferPointer => (T*)_handle.Address; + protected internal override unsafe T* BufferPointer => (T*)(ulong)_handle.Address; public override void Dispose() { diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs index 784bf2b8..ae1e9c0e 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs @@ -51,7 +51,8 @@ namespace StgSharp.Mathematics.Numeric internal static unsafe MatrixParallelWrap ScheduleTask( MatrixParallelTask* package - ) where TTaskQueue : IMatrixParallelQueue + ) + { /* int primCount = package->PrimCount; diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs index 3635fd24..67279aaa 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelQueue.cs @@ -66,10 +66,12 @@ namespace StgSharp.Mathematics.Numeric } public bool TryGetTask( - in MatrixParallelTask task + out MatrixParallelTask task ) { - if (_cursor >= _currentCapacity) { + if (_cursor >= _currentCapacity) + { + task = default; return false; } task = _currentPack[_cursor++]; diff --git a/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs b/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs index 072faeb9..b137801e 100644 --- a/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs +++ b/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs @@ -42,42 +42,36 @@ namespace StgSharp.RegularAnalysis.Abstraction where TType : unmanaged { - private HashSet _allToken = new(); + public HashSet AllNodes => AllToken; - public HashSet AllNodes - { - get { return _allToken; } - } - - public int Count - { - get { return _allToken.Count; } - } + public int Count => AllToken.Count; public TNode Root { get; internal set { - if (_allToken.Contains(value)) { + if (AllToken.Contains(value)) { field = value; } } } + private HashSet AllToken { get; } = new(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool AddNode( TNode node ) { - return _allToken.Add(node); + return AllToken.Add(node); } public bool Contains( TNode node ) { - return _allToken.Contains(node); + return AllToken.Contains(node); } public IEnumerator GetEnumerator() @@ -92,11 +86,11 @@ namespace StgSharp.RegularAnalysis.Abstraction ) : IEnumerator where TNode : ISyntaxNode where TType : unmanaged { - private bool _completed = false; + private bool _completed; private int _state, _target; // 0: not started, 1: on right, 2: ended - private Stack _recycle = []; - private Stack _stack = []; + private readonly Stack _recycle = []; + private readonly Stack _stack = []; // private TNode _lRoot; private TNode _root = root; diff --git a/StgSharp.RegularAnalysis/Abstraction/Token.cs b/StgSharp.RegularAnalysis/Abstraction/Token.cs index 17c19cc8..851f38ee 100644 --- a/StgSharp.RegularAnalysis/Abstraction/Token.cs +++ b/StgSharp.RegularAnalysis/Abstraction/Token.cs @@ -38,8 +38,6 @@ namespace StgSharp.RegularAnalysis.Abstraction public readonly struct Token where TLabel : unmanaged { - private static readonly Token EmptyToken = new Token(); - public readonly int Column; public readonly int Line; public readonly string Value; @@ -66,7 +64,7 @@ namespace StgSharp.RegularAnalysis.Abstraction Flag = flag; } - public static Token Empty => EmptyToken; + public static Token Empty { get; } = new Token(); public override bool Equals( [NotNullWhen(true)] object? obj diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.Boarder.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Boarder.cs deleted file mode 100644 index 3b8cdf5d..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/Node.Boarder.cs +++ /dev/null @@ -1,97 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Node.Boarder" -// 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 System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.RegularAnalysis -{ - internal class RegularExpressionLeftBoarderNode : RegularStateNode - { - - public RegularExpressionLeftBoarderNode( - int index, - string name - ) - { - Boarder = new GroupIndex - { - Index = index, - Name = name - }; - } - - public event EventHandler OnBoarderEntered; - - public GroupIndex Boarder { get; private set; } - - public override NodeType Type => NodeType.LEFT_BOARDER; - - public override bool IsValidateFrom( - RegularStateNode former, - RegularContext context - ) - { - return true; - } - - } - - internal class RegularExpressionRightBoarderNode : RegularStateNode - { - - public RegularExpressionRightBoarderNode( - int index, - string name - ) - { - Boarder = new GroupIndex - { - Index = index, - Name = name - }; - } - - 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/RegularMachine/Node.Branch.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs deleted file mode 100644 index dd871f26..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/Node.Branch.cs +++ /dev/null @@ -1,107 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// 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 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 sealed class RegularBranchNode : RegularStateNode - { - - private int _afterBranch; - - 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 - ) - { - if (context.StateCode == 0) - { - // branch match - label = _afterBranch; - _ = context.LastBranch.Pop(); - _lastBranch = 0; - return true; - } - - // restore sequence position - int pos = context.LastBranch.Peek(); - context.Position = pos; - if (AvailableNodes.Length > _lastBranch) - { - label = FailNodeIndex; - return false; - } - _lastBranch++; - label = AvailableNodes[_lastBranch]; - return true; - } - - } - - 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 deleted file mode 100644 index 57460392..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/Node.Char.cs +++ /dev/null @@ -1,196 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// 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/RegularMachine/Node.Sequence.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs deleted file mode 100644 index d6b27eae..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/Node.Sequence.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.RegularAnalysis -{ - internal sealed class RegularSequenceNode : RegularStateNode - { - - private string _sequence; - - public override NodeType Type => NodeType.SEQUENCE; - - public override bool IsValidateFrom( - RegularStateNode former, - RegularContext context - ) - { - int pos = context.Position + 1; - return context.CurrentCharSpan[pos.._sequence.Length].SequenceEqual(_sequence); - } - - } -} diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.cs b/StgSharp.RegularAnalysis/RegularMachine/Node.cs deleted file mode 100644 index a2a6c71c..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/Node.cs +++ /dev/null @@ -1,70 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// 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/RegularMachine/NodeType.cs b/StgSharp.RegularAnalysis/RegularMachine/NodeType.cs deleted file mode 100644 index 405a59a3..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/NodeType.cs +++ /dev/null @@ -1,65 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="RegularExpression.NodeState" -// 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 System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.RegularAnalysis -{ - internal enum NodeType - { - - // single unicode character: a、B、1、@、汉字 etc. - CHAR, - - // collections of finate characters: [abc]、[^abc]、\d、\w、\s、\D、\W、\S etc. - CHARSET, - - // 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, - - // right boarder of a sub sequnce, usually end of match group or lookaround - RIGHT_BOARDER, - - // zero length char or structure - EPSILON, - - // more than one cases to match, like alter|nation - BRANCH, - - // a sequence of nodes to match in order, each char should be fully defined but not charset - SEQUENCE - - } -} - \ No newline at end of file diff --git a/StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs b/StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs deleted file mode 100644 index edce8232..00000000 --- a/StgSharp.RegularAnalysis/RegularMachine/StateMachine.cs +++ /dev/null @@ -1,138 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// 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 class RegularContext : StateContext - { - - public int Begin { get; set; } - - public int Position { get; set; } = -1; - - public int StateCode { get; set; } = 0; - - public ReadOnlySpan CurrentCharSpan => Source.AsSpan()[Begin..Position]; - - public string Source { get; init; } - - internal Stack LastBranch { get; } = new(); - - } -} diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs b/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs index b40ece0c..e843196c 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs @@ -26,14 +26,7 @@ // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- using StgSharp.RegularAnalysis.Abstraction; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; namespace StgSharp.RegularAnalysis.TextRegex { diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexIR.cs b/StgSharp.RegularAnalysis/TextRegex/RegexIR.cs new file mode 100644 index 00000000..78bf5a25 --- /dev/null +++ b/StgSharp.RegularAnalysis/TextRegex/RegexIR.cs @@ -0,0 +1,242 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="RegexIR" +// 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 System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.RegularAnalysis.TextRegex +{ + internal enum RegexIRCommand + { + + Search = 0, + Jump = 1, + Compare = 2, + Check = 3, + Uncheck = 4, + Span = 5, + Define = 6, + Assign = 7, + Back = 8, + + } + + internal abstract class RegexIR + { + + internal abstract RegexIRCommand Command { get; } + + internal abstract void Execute(); + + } + + /// + /// Searches for a certain string pattern or charset from current position. + /// + internal sealed class RegexSearchStringIR( + string pattern + ) : RegexIR + { + + public string Pattern { get; } = pattern; + + internal override RegexIRCommand Command => RegexIRCommand.Search; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexSearchCharsetIR( + string charset + ) : RegexIR + { + + public string Charset { get; } = charset; + + internal override RegexIRCommand Command => RegexIRCommand.Search; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexSearchCharIR( + char c + ) : RegexIR + { + + public char target { get; } = c; + + internal override RegexIRCommand Command => RegexIRCommand.Search; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + /// + /// JUMP to a certain instruction index. + /// + /// + /// + /// + internal sealed class RegexJumpIR( + int target + ) : RegexIR + { + + public int TargetIndex { get; } = target; + + internal override RegexIRCommand Command => RegexIRCommand.Jump; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexBackIR( + int index + ) : RegexIR + { + + public int Target { get; } = index; + + internal override RegexIRCommand Command => RegexIRCommand.Back; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexCompareIR( + int success, + int fail + ) : RegexIR + { + + public int SuccessCase { get; } = success; + + public int FailCase { get; } = fail; + + internal override RegexIRCommand Command => RegexIRCommand.Compare; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexCheckIR : RegexIR + { + + internal override RegexIRCommand Command => RegexIRCommand.Check; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexUncheckIR : RegexIR + { + + internal override RegexIRCommand Command => RegexIRCommand.Check; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexSpanIR( + string name + ) : RegexIR + { + + public string Name { get; } = name; + + internal override RegexIRCommand Command => RegexIRCommand.Span; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexDefineCommand( + string name + ) : RegexIR + { + + public string Name { get; } = name; + + internal override RegexIRCommand Command => RegexIRCommand.Define; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } + + internal sealed class RegexAssignCommand( + string name, + T value + ) : RegexIR + { + + public string Name { get; } = name; + + public T Value { get; } = value; + + internal override RegexIRCommand Command => RegexIRCommand.Assign; + + internal override void Execute() + { + throw new NotImplementedException(); + } + + } +} diff --git a/StgSharp.RegularAnalysis/RegularMachine/Node.Count.cs b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.IRGenerate.cs similarity index 65% rename from StgSharp.RegularAnalysis/RegularMachine/Node.Count.cs rename to StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.IRGenerate.cs index b1b0792e..fa5fff99 100644 --- a/StgSharp.RegularAnalysis/RegularMachine/Node.Count.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.IRGenerate.cs @@ -1,6 +1,6 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="Node.Count" +// file="RegexInterpreter.IRGenerate" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -25,48 +25,29 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- +using StgSharp.RegularAnalysis.Abstraction; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StgSharp.RegularAnalysis +namespace StgSharp.RegularAnalysis.TextRegex { - internal class RegularExpressionCounterNode : RegularStateNode + public partial class RegexInterpreter { - private readonly int _maxCount; - private readonly int _minCount; - - public RegularExpressionCounterNode( - int minCount, - bool isEager + internal List GenerateIR( + AbstractSyntaxTree tree ) { - _minCount = minCount; - IsEager = isEager; - } + using TreeEnumerator enumerator = new(tree); + while (enumerator.MoveNext()) + { + if (true) { } + } - public bool IsEager { get; init; } - - public int Count { get; private set; } - - public override NodeType Type => NodeType.COUNT; - - public RegularStateNode LoopBack { get; set; } - - public override bool IsValidateFrom( - RegularStateNode former, - RegularContext context - ) - { - return true; - } - - public void Reset() - { - Count = 0; + return []; } } diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.Optimize.cs b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.Optimize.cs index 4e422cb9..51f8a62e 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.Optimize.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.Optimize.cs @@ -106,8 +106,8 @@ namespace StgSharp.RegularAnalysis.TextRegex int length = 0; RegexAstNode right = root.Right; RegexAstNode left = root.Left; - if (left.EqualityTypeConvert != RegexElementLabel.UNIT_SPAN && - left.EqualityTypeConvert != RegexElementLabel.UNIT) { + if (left.EqualityTypeConvert is not RegexElementLabel.UNIT_SPAN and + not RegexElementLabel.UNIT) { return false; } string str = left.Value; @@ -117,8 +117,8 @@ namespace StgSharp.RegularAnalysis.TextRegex right.EqualityTypeConvert == RegexElementLabel.CONCAT) { left = right.Left; - if (left.EqualityTypeConvert != RegexElementLabel.UNIT_SPAN && - left.EqualityTypeConvert != RegexElementLabel.UNIT) + if (left.EqualityTypeConvert is not RegexElementLabel.UNIT_SPAN and + not RegexElementLabel.UNIT) { break; } @@ -130,8 +130,8 @@ namespace StgSharp.RegularAnalysis.TextRegex right = root.Right; right.Parent = root; } - if (right.EqualityTypeConvert == RegexElementLabel.UNIT_SPAN || - right.EqualityTypeConvert == RegexElementLabel.UNIT) + if (right.EqualityTypeConvert is RegexElementLabel.UNIT_SPAN or + RegexElementLabel.UNIT) { root.Right = RegexAstNode.Empty; buffer.Add(right.Value); @@ -367,8 +367,6 @@ namespace StgSharp.RegularAnalysis.TextRegex Cases[i].Parent = UnionEnd; } UnionEnd.Right = Cases[0]; - TreeEnumerator enumerator = new TreeEnumerator(UnionBegin); - return UnionBegin; } diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs index be2a6053..b523c441 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs @@ -62,7 +62,7 @@ namespace StgSharp.RegularAnalysis.TextRegex string regex ) { - RegexInterpreter interpreter = new RegexInterpreter(); + RegexInterpreter interpreter = new(); interpreter._source = regex; bool isSuccess; try @@ -81,11 +81,12 @@ namespace StgSharp.RegularAnalysis.TextRegex private void Analyze() { - RegexTokenReader reader = new RegexTokenReader(_source); + RegexTokenReader reader = new(_source); TokenParser lexer = reader.Pipe(() => new RegexTokenParser()); while (lexer.TryReadToken(out Token token)) { + // Console.WriteLine(token.Value); if ((token.Flag & RegexElementLabel.SEQUENCE) != 0) { // char or charset diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexTokenParser.cs b/StgSharp.RegularAnalysis/TextRegex/RegexTokenParser.cs index f7888def..452a65a1 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexTokenParser.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexTokenParser.cs @@ -68,6 +68,7 @@ namespace StgSharp.RegularAnalysis.TextRegex } } else { + Console.WriteLine("returns empty"); return Token.Empty; } } @@ -82,7 +83,7 @@ namespace StgSharp.RegularAnalysis.TextRegex return false; } t = ReadToken(); - return t == Token.Empty; + return t != Token.Empty; } } diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs b/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs index c07a4de9..bfd0a23c 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="RegexTokenReader" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// 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 @@ -45,7 +45,9 @@ namespace StgSharp.RegularAnalysis.TextRegex public RegexTokenReader() { } - public RegexTokenReader(string source) + public RegexTokenReader( + string source + ) { _source = source; } @@ -65,9 +67,11 @@ namespace StgSharp.RegularAnalysis.TextRegex { string value = _source[(pos + 1)..(pos + 3)]; pos += 4; - if (uint.TryParse(value, out uint code) && Rune.TryCreate(code, out Rune result)) + if (uint.TryParse(value, out uint code) && + Rune.TryCreate(code, out Rune result)) { - return new Token(result.ToString(), 0, pos, RegexElementLabel.UNIT); + return new Token(result.ToString(), 0, pos, + RegexElementLabel.UNIT); } else { throw new InvalidCastException($"Failed to convert {value} to a valid ascii code point."); @@ -76,9 +80,11 @@ namespace StgSharp.RegularAnalysis.TextRegex { string value = _source[(pos + 1)..(pos + 5)]; pos += 6; - if (uint.TryParse(value, out uint code) && Rune.TryCreate(code, out Rune result)) + if (uint.TryParse(value, out uint code) && + Rune.TryCreate(code, out Rune result)) { - return new Token(result.ToString(), 0, pos, RegexElementLabel.UNIT); + return new Token(result.ToString(), 0, pos, + RegexElementLabel.UNIT); } else { throw new InvalidCastException($"Failed to convert {value} to a valid unicode code point."); @@ -112,21 +118,24 @@ namespace StgSharp.RegularAnalysis.TextRegex { int length = (i - pos - 1); position = i + 1; - return new Token(_source[(pos)..(i + 1)], 0, position, + return new Token(_source[(pos)..(i + 1)], 0, + position, RegexElementLabel.UNIT_SET); } } throw new InvalidOperationException("Unclosed character set"); case '|': position = pos + 1; - return new Token(_source[(pos)..(pos + 1)], 0, pos, RegexElementLabel.ALT); + return new Token(_source[(pos)..(pos + 1)], 0, pos, + RegexElementLabel.ALT); case '(': // very comlex here return ReadGroupBeginToken(); case ')': position = pos + 1; - return new Token(_source[(pos)..(pos + 1)], 0, pos, RegexElementLabel.GROUP_END); + return new Token(_source[(pos)..(pos + 1)], 0, pos, + RegexElementLabel.GROUP_END); case '{': for (int i = pos + 1; i < _source.Length; i++) { @@ -141,19 +150,25 @@ namespace StgSharp.RegularAnalysis.TextRegex case '*' or '+': int count = _source[pos + 1] == '?' ? 2 : 1; position = pos + count; - return new Token(_source[(pos)..(pos + count)], 0, pos, RegexElementLabel.COUNT); + return new Token(_source[(pos)..(pos + count)], 0, pos, + RegexElementLabel.COUNT); case '?': position = pos + 1; - return new Token(_source[(pos)..(pos + 1)], 0, pos, RegexElementLabel.COUNT); + return new Token(_source[(pos)..(pos + 1)], 0, pos, + RegexElementLabel.COUNT); case '.': - return new Token(_source[(pos)..(pos + 1)], 0, pos, RegexElementLabel.UNIT); + return new Token(_source[(pos)..(pos + 1)], 0, pos, + RegexElementLabel.UNIT); default: position = pos + 1; - return new Token(_source[(pos)..(pos + 1)], 0, pos, RegexElementLabel.UNIT); + return new Token(_source[(pos)..(pos + 1)], 0, pos, + RegexElementLabel.UNIT); } } - public bool TryReadToken(out Token t) + public bool TryReadToken( + out Token t + ) { if (IsEmpty) { @@ -161,7 +176,7 @@ namespace StgSharp.RegularAnalysis.TextRegex return false; } t = ReadToken(); - return Token.Empty == t; + return Token.Empty != t; } private Token ReadGroupBeginToken() diff --git a/StgSharpDebug/Program.cs b/StgSharpDebug/Program.cs index 4b7637f1..bef92bbd 100644 --- a/StgSharpDebug/Program.cs +++ b/StgSharpDebug/Program.cs @@ -52,10 +52,11 @@ namespace StgSharp // .UseModule() .InitializeModule(); - // TestRegexAnalyse.Run(); + TestRegexAnalyse.Run(); + // TestHlsf(); - TlsfStressTest.Run(); + // TlsfStressTest.Run(); // TestSwiss(); // TestL4Prefetch(); diff --git a/StgSharpDebug/TestRegexAnalyse.cs b/StgSharpDebug/TestRegexAnalyse.cs index f52b4e51..b4d4ae83 100644 --- a/StgSharpDebug/TestRegexAnalyse.cs +++ b/StgSharpDebug/TestRegexAnalyse.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="TestRegexAnalyse" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// 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 @@ -42,7 +42,9 @@ namespace StgSharp @"http|https|ftp|ftps", @"abc[0-9]x|abc[0-9]y|abd[0-9]x|abd[0-9]y|xyz", @"get_name|get_value|get_type|set_name|set_value|set_type", - @"helix|hello|help|hero|hers|her" ]; + @"helix|hello|help|hero|hers|her", + @"http|https|ftp|ftps" + ]; public static void Run() { @@ -51,7 +53,7 @@ namespace StgSharp RegexInterpreter interpreter = RegexInterpreter.Analyze(regex); AbstractSyntaxTree tree = interpreter.Tree; Console.WriteLine($"result of \"{regex}\""); - TreeEnumerator enumerator = new TreeEnumerator(tree); + TreeEnumerator enumerator = new(tree); while (enumerator.MoveNext()) { RegexAstNode node = enumerator.Current; diff --git a/future/ngra-regex-ir.md b/future/ngra-regex-ir.md new file mode 100644 index 00000000..ee2641e1 --- /dev/null +++ b/future/ngra-regex-ir.md @@ -0,0 +1,27 @@ + +# 适用于NGRA字符串正则的IR形式 + +## 两个指针 + +1. 活动指针,记录当前的搜索位置,下文“不更新活动指针”的意思是算计结束后自行对活动指针进行复位 +2. 锚点指针,记录一个区间的开始位置 + +## 检查点 + +检查点是锚点指针的一种形式,以栈形态存储,创建检查点时,上一个检查点自动压栈,并用当前检查点替换为当前的锚点指针 + +## 符号区 + +使用DEFINE指令定义的符号定义在符号区中,符号的类型通过第一次赋值确定,源生成模式下,可以通过第一个赋值指令推导其类型 + +## 算子 + +1. 搜索算子(SEARCH %str; SEARCH %unicode;SERCH %set_expression),向后搜索确定长度序列或者满足规则的字符集,更新活动指针,不更新锚点指针,搜索结果保存在全局上下文中 +2. 跳转算子(JMP %cmd_idx),跳转到指定的IR指令之前,不变化任何指针, +3. 回到(BACK %cmd_idx %count)跳转到一个跳自身位置之前的位置,并更新跳转次数,不变化任何的指针,%count应当是使用DEFINE指令定义好的符号 +4. 比较指令(CONDITION %cmd_true %cmd_fail),比较前一条SEARCH指令是否成功,并指定跳转到指定的位置,如果某种条件不需要跳转,请使用0进行填充 +5. 检查点指令(CHECK),将锚点指针强制拉取到活动指针的位置 +6. 弹出检查点(UNCHECK),将一个检查点撤销并销毁 +7. 划分区间指令(SPAN %name),将锚点指针和活动指针之间的部分划分为一个Span<>,并弹出对应的检查点 +8. 定义指令(DEFINE %symbol)定义一个符号 +9. 赋值指令(ASSIGN %symbol %value)将符号设定为值