From 807658111c48da9d1c4a140b16413f2c447ca724 Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Mon, 9 Feb 2026 18:08:49 +0800 Subject: [PATCH] fix errors in interpreter. add a enumerator for tree. working on tree optimizer --- ...tionary.cs => IBidirectionalDictionary.cs} | 23 ++- .../Abstraction/AbstractSyntaxTree.cs | 143 +++++++++++++----- .../Abstraction/CompileStack.cs | 2 +- .../Abstraction/ISyntaxNode.cs | 26 +++- StgSharp.RegularAnalysis/Global.cs | 35 +++++ .../TextRegex/RegexAstNode.cs | 72 +++++---- .../TextRegex/RegexElementLabel.cs | 2 +- .../TextRegex/RegexInterpreter.cs | 73 ++++++--- .../TextRegex/RegexTokenReader.cs | 4 +- StgSharpDebug/TestRegexAnalyse.cs | 14 +- 10 files changed, 288 insertions(+), 106 deletions(-) rename StgSharp.Common/Collections/{IBidrirectionalDictionary.cs => IBidirectionalDictionary.cs} (88%) create mode 100644 StgSharp.RegularAnalysis/Global.cs diff --git a/StgSharp.Common/Collections/IBidrirectionalDictionary.cs b/StgSharp.Common/Collections/IBidirectionalDictionary.cs similarity index 88% rename from StgSharp.Common/Collections/IBidrirectionalDictionary.cs rename to StgSharp.Common/Collections/IBidirectionalDictionary.cs index 200558e8..47b551c7 100644 --- a/StgSharp.Common/Collections/IBidrirectionalDictionary.cs +++ b/StgSharp.Common/Collections/IBidirectionalDictionary.cs @@ -1,6 +1,6 @@ //----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="IBidrirectionalDictionary" +// file="IBidirectionalDictionary" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -32,7 +32,9 @@ namespace StgSharp.Collections public interface IBidirectionalDictionary : IDictionary { - TFirst this[TSecond key] { get; set; } + TFirst this[ + TSecond key + ] { get; set; } ICollection FirstIndex { get; } @@ -53,7 +55,9 @@ namespace StgSharp.Collections /// true if the contains an element with /// the specified key; otherwise, false. /// - bool Contains(TSecond key); + bool Contains( + TSecond key + ); /// /// Determines whether the contains the @@ -66,16 +70,23 @@ namespace StgSharp.Collections /// true if the contains an element with /// the specified key; otherwise, false. /// - bool Contains(TFirst key); + bool Contains( + TFirst key + ); - bool TryGetValue(TSecond key, out TFirst value); + bool TryGetValue( + TSecond key, + out TFirst value + ); #pragma warning disable CA1033 ICollection IDictionary.Keys => FirstIndex; ICollection IDictionary.Values => SecondIndex; - bool IDictionary.ContainsKey(TFirst key) + bool IDictionary.ContainsKey( + TFirst key + ) { return Contains(key); } diff --git a/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs b/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs index e946e5dc..fe7f85eb 100644 --- a/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs +++ b/StgSharp.RegularAnalysis/Abstraction/AbstractSyntaxTree.cs @@ -1,30 +1,27 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="AbstractSyntaxTree.cs" +// file="AbstractSyntaxTree" // 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 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. +// 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. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- @@ -34,18 +31,18 @@ using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Xml.Schema; namespace StgSharp.RegularAnalysis.Abstraction { - public sealed class AbstractSyntaxTree where TNode: ISyntaxNode where TType: unmanaged + public sealed class AbstractSyntaxTree where TNode : ISyntaxNode + where TType : unmanaged { private HashSet _allToken = new(); - private TNode _root; - public HashSet AllNodes { get { return _allToken; } @@ -68,12 +65,16 @@ namespace StgSharp.RegularAnalysis.Abstraction } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool AddNode(TNode node) + public bool AddNode( + TNode node + ) { return _allToken.Add(node); } - public bool Contains(TNode node) + public bool Contains( + TNode node + ) { return _allToken.Contains(node); } @@ -87,23 +88,26 @@ namespace StgSharp.RegularAnalysis.Abstraction { private int _state,_target; // 0: not started, 1: on right, 2: ended - private Stack _stack, _listStack; + private Stack _recycle; + private Stack _stack; private TNode _lRoot; private TNode _root; - public Enumerator(AbstractSyntaxTree tree) + public Enumerator( + AbstractSyntaxTree tree + ) { - _root = tree._root; + _root = tree.Root; _stack = []; - _listStack = []; + _recycle = []; } public TNode Current { get { - if (_stack.TryPeek(out TNode? node)) { - return node; + if (_stack.TryPeek(out Record? r)) { + return r.Node; } return TNode.Empty; } @@ -116,8 +120,48 @@ namespace StgSharp.RegularAnalysis.Abstraction public bool MoveNext() { - if (_stack.TryPop(out TNode? cur)) { } - _stack.Push(_root); + while (_stack.TryPeek(out Record? cur)) + { + switch (cur.State) + { + case 0: + cur.State++; + if (TNode.IsNullOrEmpty(cur.Node.Left)) + { + goto case 1; + } else + { + _stack.Push(GetNewRecord(cur.Node.Left)); + return true; + } + case 1: + cur.State++; + if (TNode.IsNullOrEmpty(cur.Node.Right)) + { + goto case 2; + } else + { + _stack.Push(GetNewRecord(cur.Node.Right)); + return true; + } + case 2: + if (TNode.IsNullOrEmpty(cur.Node.Next)) + { + _recycle.Push(_stack.Pop()); + if (_stack.Count == 0) { + return false; + } + } else + { + _stack.Push(GetNewRecord(cur.Node.Next)); + return true; + } + break; + default: + break; + } + } + _stack.Push(GetNewRecord(_root)); return true; } @@ -127,8 +171,33 @@ namespace StgSharp.RegularAnalysis.Abstraction _state = 0; } + private Record GetNewRecord( + TNode node + ) + { + if (_recycle.TryPop(out Record? r)) + { + r.State = 0; + r.Node = node; + return r; + } + return new Record(node, 0); + } + object IEnumerator.Current => Current; + private class Record( + TNode node, + int state + ) + { + + public int State { get; set; } = state; + + public TNode Node { get; set; } = node; + + } + } } diff --git a/StgSharp.RegularAnalysis/Abstraction/CompileStack.cs b/StgSharp.RegularAnalysis/Abstraction/CompileStack.cs index 680cd853..285b8d78 100644 --- a/StgSharp.RegularAnalysis/Abstraction/CompileStack.cs +++ b/StgSharp.RegularAnalysis/Abstraction/CompileStack.cs @@ -130,7 +130,7 @@ namespace StgSharp.RegularAnalysis.Abstraction public TNode PopOperand( ) { - if (OperatorInDepthCount > 0) { + if (OperandInDepthCount > 0) { return _operands.Pop(); } return TNode.Empty; diff --git a/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs b/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs index 45e7410f..0d816001 100644 --- a/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs +++ b/StgSharp.RegularAnalysis/Abstraction/ISyntaxNode.cs @@ -1,9 +1,9 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="ISyntaxNode" // 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 @@ -31,11 +31,13 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; namespace StgSharp.RegularAnalysis.Abstraction { - public interface ISyntaxNode where TNode: ISyntaxNode where TLabel: unmanaged + public interface ISyntaxNode where TNode : ISyntaxNode + where TLabel : unmanaged { long NodeFlag { get; } @@ -60,9 +62,21 @@ namespace StgSharp.RegularAnalysis.Abstraction protected internal int EnumState { get; set; } - void AppendNode(TNode nextToken); + void AppendNode( + TNode nextToken + ); - void PrependNode(TNode previousNode); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static virtual bool IsNullOrEmpty( + TNode node + ) + { + return node is null || node.Equals(TNode.Empty); + } + + void PrependNode( + TNode previousNode + ); } } diff --git a/StgSharp.RegularAnalysis/Global.cs b/StgSharp.RegularAnalysis/Global.cs new file mode 100644 index 00000000..c9bc3b52 --- /dev/null +++ b/StgSharp.RegularAnalysis/Global.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="Global" +// 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.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +[assembly: InternalsVisibleTo("StgSharpDebug")] \ No newline at end of file diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs b/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs index a3b14ad2..9e6913f4 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs @@ -1,30 +1,27 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="RegexAstNode.cs" +// file="RegexAstNode" // 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 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. +// 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. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- @@ -44,7 +41,9 @@ namespace StgSharp.RegularAnalysis.TextRegex private RegexAstNode _left, _right; - public RegexAstNode(Token source) + public RegexAstNode( + Token source + ) { Source = source; } @@ -95,13 +94,18 @@ namespace StgSharp.RegularAnalysis.TextRegex public Token Source { get; } - public void AppendNode(RegexAstNode nextToken) { } + public void AppendNode( + RegexAstNode nextToken + ) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static (bool Valid,int Value) ComparePrecedence(RegexElementLabel left, RegexElementLabel right) + public static (bool Valid,int Value) ComparePrecedence( + RegexElementLabel left, + RegexElementLabel right + ) { - left |= RegexElementLabel.OPERATOR; - right |= RegexElementLabel.OPERATOR; + left &= RegexElementLabel.OPERATOR; + right &= RegexElementLabel.OPERATOR; int v_left = (int)left, v_right = (int)right; if (v_left == 0 || v_right == 0) { return (false,0); @@ -109,9 +113,15 @@ namespace StgSharp.RegularAnalysis.TextRegex return (true,v_left - v_right); } - public void PrependNode(RegexAstNode previousNode) { } + public void PrependNode( + RegexAstNode previousNode + ) { } - public static bool TryMergeUnit(RegexAstNode prev, RegexAstNode next, out RegexAstNode result) + public static bool TryMergeUnit( + RegexAstNode prev, + RegexAstNode next, + out RegexAstNode result + ) { Token pSource = prev.Source; Token nSource = next.Source; diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexElementLabel.cs b/StgSharp.RegularAnalysis/TextRegex/RegexElementLabel.cs index ccaac106..0fc826d6 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexElementLabel.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexElementLabel.cs @@ -49,7 +49,7 @@ namespace StgSharp.RegularAnalysis.TextRegex SEQUENCE = UNIT | UNIT_SPAN | UNIT_SET, OPERATOR = COUNT | ALT | CONCAT, ATOM_BEGIN = SEQUENCE | GROUP_BEGIN , - ATOM_END = SEQUENCE | GROUP_END, + ATOM_END = SEQUENCE | GROUP_END | COUNT, } } diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs index b1cfed9c..1cc5c746 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexInterpreter.cs @@ -1,9 +1,9 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="RegexInterpreter" // 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 @@ -29,6 +29,7 @@ using StgSharp.RegularAnalysis.Abstraction; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Text; @@ -46,7 +47,20 @@ namespace StgSharp.RegularAnalysis.TextRegex private RegexInterpreter() { } - public static RegexInterpreter Analyze(string regex) + internal AbstractSyntaxTree Tree + { + get + { + if (_interpreteException != null) { + throw new InvalidOperationException("The regex interpretation failed.", _interpreteException); + } + return _tree; + } + } + + public static RegexInterpreter Analyze( + string regex + ) { RegexInterpreter interpreter = new RegexInterpreter(); interpreter._source = regex; @@ -114,7 +128,7 @@ namespace StgSharp.RegularAnalysis.TextRegex // process operator by precedence while (_stack.TryPeekOperator(out RegexAstNode topOp)) { - (bool Valid, int Value) cmp = RegexAstNode.ComparePrecedence(token.Flag, topOp.Source.Flag); + (bool Valid, int Value) cmp = RegexAstNode.ComparePrecedence(topOp.Source.Flag, token.Flag); if (!cmp.Valid) { throw new InvalidOperationException("Operators with same precedence are not supported."); @@ -157,31 +171,53 @@ namespace StgSharp.RegularAnalysis.TextRegex { // phase0: scan container and remove no parent nodes _tree.AllNodes.RemoveWhere(node => node.Parent == null && node != _tree.Root); + HashSet.Enumerator enumerator = _tree.AllNodes.GetEnumerator(); // phase1: ALT flatten - int opCount = 0, cycle = 0; - do + while (enumerator.MoveNext()) { - cycle++; - } while (opCount != 0 && cycle < 16); + RegexAstNode node = enumerator.Current; + if ((RegexElementLabel)node.NodeFlag == RegexElementLabel.ALT) + { + RegexAstNode right, left = node.Left; + while (node.Right.Source.Flag == RegexElementLabel.ALT) + { + // flatten a alternation to left linked list of root ALT + right = node.Right; + RegexAstNode nextAlt = right.Left; + left.Next = nextAlt; + nextAlt.Previous = left; + nextAlt.Parent = node; + right.Left = RegexAstNode.Empty; + left = nextAlt; + + // remove the right ALT node and connect its right child to current node + node.Right = right.Right; + right.Right.Parent = node; + } + + // connect the last ALT node to the right child of current node + right = node.Right; + left.Next = right; + right.Previous = left; + } + } // phase2: ALT merge - opCount = 0; - cycle = 0; - do - { - opCount = 1; - } while (opCount != 0); + // phase3: CONCAT merge } - private void ProcessOperator(RegexAstNode op) + private void ProcessOperator( + RegexAstNode op + ) { Console.WriteLine($"Processing a {op.Source.Flag} operator"); if (op.EqualityTypeConvert == RegexElementLabel.CONCAT) { - if (_stack.TryPopOperand(out RegexAstNode? _1) && _stack.TryPopOperand(out RegexAstNode? _2)) + if (_stack.TryPopOperand(out RegexAstNode? _1) && + _stack.TryPopOperand(out RegexAstNode? _2)) { op.Left = _2; op.Right = _1; @@ -207,7 +243,8 @@ namespace StgSharp.RegularAnalysis.TextRegex } } else if (op.EqualityTypeConvert == RegexElementLabel.ALT) { - if (_stack.TryPopOperand(out RegexAstNode? _1) && _stack.TryPopOperand(out RegexAstNode? _2)) + if (_stack.TryPopOperand(out RegexAstNode? _1) && + _stack.TryPopOperand(out RegexAstNode? _2)) { op.Left = _1; op.Right = _2; diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs b/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs index dc83c19d..af43e523 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexTokenReader.cs @@ -73,7 +73,7 @@ namespace StgSharp.RegularAnalysis.TextRegex { int length = (i - pos - 1); position = i + 1; - return new Token(_source[(pos - 1)..(i - 1)], 0, + return new Token(_source[(pos)..(i + 1)], 0, position, RegexElementLabel.UNIT_SET); } @@ -93,7 +93,7 @@ namespace StgSharp.RegularAnalysis.TextRegex if (_source[i] == '}') { position = i + 1; - return new Token(_source[(pos)..(i - 1)], 0, pos, + return new Token(_source[(pos)..(i + 1)], 0, pos, RegexElementLabel.COUNT); } } diff --git a/StgSharpDebug/TestRegexAnalyse.cs b/StgSharpDebug/TestRegexAnalyse.cs index cd31e1eb..bf8f29b8 100644 --- a/StgSharpDebug/TestRegexAnalyse.cs +++ b/StgSharpDebug/TestRegexAnalyse.cs @@ -1,9 +1,9 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // 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 @@ -38,11 +38,17 @@ namespace StgSharp public class TestRegexAnalyse { - private const string regex = @"abc(?abc)"; + private const string regex = @"ab[1-9]+(?abc)"; public static void Run() { RegexInterpreter interpreter = RegexInterpreter.Analyze(regex); + AbstractSyntaxTree tree = interpreter.Tree; + Console.WriteLine(); + Console.WriteLine(); + foreach (RegexAstNode node in tree) { + Console.WriteLine($"{node.Source.Value}\t{node.Source.Flag}"); + } } }