prefix replaces CONDITION
This commit is contained in:
@@ -3,3 +3,8 @@
|
|||||||
|
|
||||||
|
|
||||||
[2026-05-13 11:33:26.040] [Info] Program StgSharpDebug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null on GF-CHEN-LIU Started.
|
[2026-05-13 11:33:26.040] [Info] Program StgSharpDebug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null on GF-CHEN-LIU Started.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[2026-07-06 16:49:29.987] [Info] Program StgSharpDebug, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null on GF-CHEN-LIU Started.
|
||||||
|
|||||||
@@ -0,0 +1,449 @@
|
|||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// file="RegexAnalyzerFrontEnd.PrefixEmit"
|
||||||
|
// 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.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace StgSharp.RegularAnalysis.Text
|
||||||
|
{
|
||||||
|
public static partial class RegexAnalyzerFrontEnd
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static List<RegexIR> EmitPrefix(
|
||||||
|
List<RegexIR> irList
|
||||||
|
)
|
||||||
|
{
|
||||||
|
List<RegexIR> origin = irList;
|
||||||
|
List<RegexIR> result = new(origin.Count);
|
||||||
|
Span<RegexIR> origin_span = CollectionsMarshal.AsSpan(origin);
|
||||||
|
|
||||||
|
int region_name = 1;
|
||||||
|
EmitPrefix(origin_span, result, 0, 0);
|
||||||
|
FixLineObservation(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
void EmitPrefix(
|
||||||
|
ReadOnlySpan<RegexIR> region,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReadOnlySpan<RegexIR> emit_window;
|
||||||
|
int index = 0;
|
||||||
|
while (index < region.Length)
|
||||||
|
{
|
||||||
|
emit_window = region[index..];
|
||||||
|
|
||||||
|
int emitResult;
|
||||||
|
if ((emitResult = TryEmitGroupFindPack(emit_window, result, currentRegion, lineBase)) > 0)
|
||||||
|
{
|
||||||
|
index += emitResult;
|
||||||
|
} else if ((emitResult = TryEmitTryGroupTail(emit_window, result, currentRegion, lineBase)) > 0)
|
||||||
|
{
|
||||||
|
index += emitResult;
|
||||||
|
} else if ((emitResult = TryEmitAltChain(emit_window, result, currentRegion, lineBase)) > 0)
|
||||||
|
{
|
||||||
|
index += emitResult;
|
||||||
|
} else if ((emitResult = TryEmitAltSuccessTail(emit_window, result, currentRegion, lineBase)) > 0)
|
||||||
|
{
|
||||||
|
index += emitResult;
|
||||||
|
} else if ((emitResult = TryEmitAltFailTail(emit_window, result, currentRegion, lineBase)) > 0)
|
||||||
|
{
|
||||||
|
index += emitResult;
|
||||||
|
} else if ((emitResult = TryEmitTryIR(emit_window, result, currentRegion, lineBase)) > 0)
|
||||||
|
{
|
||||||
|
index += emitResult;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
result.Add(CloneIR(emit_window[0], currentRegion));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int TryEmitTryGroupTail(
|
||||||
|
ReadOnlySpan<RegexIR> origin,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (origin.Length < 5 || origin[0] is not RegexTryIR _try) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tailOffset = _try.CommandCount + 1;
|
||||||
|
if (origin.Length < tailOffset + 3 ||
|
||||||
|
origin[tailOffset] is not RegexConditionIR { SuccessCase: 2, FailCase: 1 } condition ||
|
||||||
|
origin[tailOffset + 1] is not RegexPopIR { IsSuccess: false } pop ||
|
||||||
|
origin[tailOffset + 2] is not RegexPackIR { Condition: true } pack) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tryOutputIndex = result.Count;
|
||||||
|
int emitCount = TryEmitTryIR(
|
||||||
|
origin,
|
||||||
|
result,
|
||||||
|
currentRegion,
|
||||||
|
lineBase,
|
||||||
|
foldSingleInstructionTry: false);
|
||||||
|
if (emitCount <= 0 || result[tryOutputIndex] is not RegexTryIR emittedTry) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = condition;
|
||||||
|
int regionId = emittedTry.Prefix.WorkingRegion;
|
||||||
|
|
||||||
|
RegexIR prefixedPop = CloneIR(pop, regionId);
|
||||||
|
ApplyPrefix(
|
||||||
|
prefixedPop,
|
||||||
|
regionId,
|
||||||
|
RegexIRPrefixMask.Prev_Fail | RegexIRPrefixMask.Observe_Region,
|
||||||
|
regionId);
|
||||||
|
|
||||||
|
RegexIR prefixedPack = CloneIR(pack, regionId);
|
||||||
|
ApplyPrefix(
|
||||||
|
prefixedPack,
|
||||||
|
regionId,
|
||||||
|
RegexIRPrefixMask.Prev_Success | RegexIRPrefixMask.Observe_Region,
|
||||||
|
regionId);
|
||||||
|
|
||||||
|
result.Add(prefixedPop);
|
||||||
|
result.Add(prefixedPack);
|
||||||
|
return emitCount + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TryEmitAltChain(
|
||||||
|
ReadOnlySpan<RegexIR> origin,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (origin.Length < 3 ||
|
||||||
|
origin[0] is not RegexConditionIR { SuccessCase: 1, FailCase: 2 } ||
|
||||||
|
origin[1] is not RegexPopIR { IsSuccess: true } ||
|
||||||
|
origin[2] is not RegexTryIR) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int observeRegion = currentRegion;
|
||||||
|
RegexIRPrefixMask observeMask = RegexIRPrefixMask.Observe_Region;
|
||||||
|
int observeSource = currentRegion;
|
||||||
|
if (result.Count > 0)
|
||||||
|
{
|
||||||
|
RegexIR previous = result[^1];
|
||||||
|
observeRegion = GetObservedRegion(previous, currentRegion);
|
||||||
|
GetObservation(previous, result, lineBase, currentRegion, out observeMask, out observeSource);
|
||||||
|
ApplyPrefix(previous, observeRegion, RegexIRPrefixMask.Pop_Success, observeRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegexIRPrefixMask mask = RegexIRPrefixMask.Prev_Fail | observeMask;
|
||||||
|
int emit_count = TryEmitTryIR(origin[2..], result, currentRegion, lineBase, mask, observeSource, observeRegion);
|
||||||
|
return emit_count < 0 ? -1 : emit_count + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TryEmitAltSuccessTail(
|
||||||
|
ReadOnlySpan<RegexIR> origin,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (origin.Length < 2 ||
|
||||||
|
origin[0] is not RegexConditionIR { SuccessCase: 1, FailCase: 2 } ||
|
||||||
|
origin[1] is not RegexPopIR { IsSuccess: true } ||
|
||||||
|
result.Count == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegexIR previous = result[^1];
|
||||||
|
int observeRegion = GetObservedRegion(previous, currentRegion);
|
||||||
|
ApplyPrefix(previous, observeRegion, RegexIRPrefixMask.Pop_Success, observeRegion);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TryEmitAltFailTail(
|
||||||
|
ReadOnlySpan<RegexIR> origin,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (origin.Length < 1 ||
|
||||||
|
origin[0] is not RegexPopIR { IsSuccess: false } pop ||
|
||||||
|
result.Count == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegexIR previous = result[^1];
|
||||||
|
if ((previous.Prefix.Mask & RegexIRPrefixMask.Pop_Success) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetObservation(
|
||||||
|
previous,
|
||||||
|
result,
|
||||||
|
lineBase,
|
||||||
|
currentRegion,
|
||||||
|
out RegexIRPrefixMask observeMask,
|
||||||
|
out int observeSource);
|
||||||
|
RegexIR prefixedPop = CloneIR(pop, currentRegion);
|
||||||
|
ApplyPrefix(
|
||||||
|
prefixedPop,
|
||||||
|
currentRegion,
|
||||||
|
RegexIRPrefixMask.Prev_Fail | observeMask,
|
||||||
|
observeSource);
|
||||||
|
result.Add(prefixedPop);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert TRY into region
|
||||||
|
int TryEmitTryIR(
|
||||||
|
ReadOnlySpan<RegexIR> origin,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase,
|
||||||
|
RegexIRPrefixMask mask = 0,
|
||||||
|
int observeSource = 0,
|
||||||
|
int reuseRegion = 0,
|
||||||
|
bool foldSingleInstructionTry = true
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (origin.Length == 0 || origin[0] is not RegexTryIR _try) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int commandCount = _try.CommandCount;
|
||||||
|
if (origin.Length < commandCount + 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int regionId = reuseRegion == 0 ? region_name : reuseRegion;
|
||||||
|
if (reuseRegion == 0) {
|
||||||
|
region_name++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foldSingleInstructionTry &&
|
||||||
|
commandCount == 1 &&
|
||||||
|
IsFoldableSingleTryInstruction(origin[1])) {
|
||||||
|
RegexIR folded = CloneIR(origin[1], regionId);
|
||||||
|
int foldedObserveSource =
|
||||||
|
(mask & RegexIRPrefixMask.ObserveMethod) != 0 ?
|
||||||
|
observeSource :
|
||||||
|
_try.Prefix.ObserveSource;
|
||||||
|
folded.Prefix = new RegexIRPrefix(
|
||||||
|
regionId,
|
||||||
|
folded.Prefix.Mask | _try.Prefix.Mask | mask,
|
||||||
|
foldedObserveSource);
|
||||||
|
result.Add(folded);
|
||||||
|
return commandCount + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RegexIR> sub_ir = new(commandCount);
|
||||||
|
ReadOnlySpan<RegexIR> try_region = origin.Slice(1, commandCount);
|
||||||
|
EmitPrefix(try_region, sub_ir, regionId, lineBase + result.Count + 1);
|
||||||
|
|
||||||
|
RegexTryIR newTry = new(sub_ir.Count)
|
||||||
|
{
|
||||||
|
IsFullyOptimized = _try.IsFullyOptimized,
|
||||||
|
Prefix = new RegexIRPrefix(regionId, _try.Prefix.Mask | mask, observeSource)
|
||||||
|
};
|
||||||
|
result.Add(newTry);
|
||||||
|
result.AddRange(sub_ir);
|
||||||
|
return commandCount + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TryEmitGroupFindPack(
|
||||||
|
ReadOnlySpan<RegexIR> origin,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int currentRegion,
|
||||||
|
int lineBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (origin.Length < 5 ||
|
||||||
|
origin[0] is not RegexTryIR { CommandCount: 1 } _try ||
|
||||||
|
origin[1] is not RegexFindComplexIR find ||
|
||||||
|
origin[2] is not RegexConditionIR { SuccessCase: 2, FailCase: 1 } ||
|
||||||
|
origin[3] is not RegexPopIR { IsSuccess: false } ||
|
||||||
|
origin[4] is not RegexPackIR { Condition: true } pack) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int regionId = region_name;
|
||||||
|
region_name++;
|
||||||
|
|
||||||
|
RegexIRPrefixMask findMask = find.Prefix.Mask | _try.Prefix.Mask;
|
||||||
|
int findObserveSource =
|
||||||
|
(find.Prefix.Mask & RegexIRPrefixMask.ObserveMethod) != 0 ?
|
||||||
|
find.Prefix.ObserveSource :
|
||||||
|
_try.Prefix.ObserveSource;
|
||||||
|
|
||||||
|
RegexFindComplexIR newFind = new(find.IsNearest, find.CommandCount)
|
||||||
|
{
|
||||||
|
IsFullyOptimized = find.IsFullyOptimized,
|
||||||
|
Prefix = new RegexIRPrefix(regionId, findMask, findObserveSource)
|
||||||
|
};
|
||||||
|
RegexPackIR newPack = new(pack.Condition, pack.GroupName)
|
||||||
|
{
|
||||||
|
Prefix = new RegexIRPrefix(
|
||||||
|
regionId,
|
||||||
|
pack.Prefix.Mask | RegexIRPrefixMask.Prev_Success | RegexIRPrefixMask.Observe_Line,
|
||||||
|
-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
result.Add(newFind);
|
||||||
|
result.Add(newPack);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetObservedRegion(
|
||||||
|
RegexIR ir,
|
||||||
|
int currentRegion
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ir.Prefix.WorkingRegion == 0 ? currentRegion : ir.Prefix.WorkingRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetObservation(
|
||||||
|
RegexIR ir,
|
||||||
|
List<RegexIR> result,
|
||||||
|
int lineBase,
|
||||||
|
int currentRegion,
|
||||||
|
out RegexIRPrefixMask observeMask,
|
||||||
|
out int observeSource
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (IsLineObservable(ir))
|
||||||
|
{
|
||||||
|
observeMask = RegexIRPrefixMask.Observe_Line;
|
||||||
|
observeSource = -1;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
observeMask = RegexIRPrefixMask.Observe_Region;
|
||||||
|
observeSource = GetObservedRegion(ir, currentRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FixLineObservation(
|
||||||
|
List<RegexIR> result
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < result.Count; i++)
|
||||||
|
{
|
||||||
|
RegexIRPrefix prefix = result[i].Prefix;
|
||||||
|
if ((prefix.Mask & RegexIRPrefixMask.Observe_Line) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[i].Prefix = new RegexIRPrefix(
|
||||||
|
prefix.WorkingRegion,
|
||||||
|
prefix.Mask,
|
||||||
|
i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsFoldableSingleTryInstruction(
|
||||||
|
RegexIR ir
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return IsLineObservable(ir) &&
|
||||||
|
(ir.Prefix.Mask & RegexIRPrefixMask.ExeCondition) == 0 &&
|
||||||
|
(ir.Prefix.Mask & RegexIRPrefixMask.ObserveMethod) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsLineObservable(
|
||||||
|
RegexIR ir
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return ir is RegexMatchSeqIR or
|
||||||
|
RegexMatchSetIR or
|
||||||
|
RegexCountSeqIR or
|
||||||
|
RegexCountSetIR or
|
||||||
|
RegexFindSeqIR or
|
||||||
|
RegexFindComplexIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyPrefix(
|
||||||
|
RegexIR ir,
|
||||||
|
int workingRegion,
|
||||||
|
RegexIRPrefixMask mask,
|
||||||
|
int observeSource
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ir.Prefix = new RegexIRPrefix(
|
||||||
|
workingRegion,
|
||||||
|
ir.Prefix.Mask | mask,
|
||||||
|
observeSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegexIR CloneIR(
|
||||||
|
RegexIR ir,
|
||||||
|
int currentRegion
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RegexIR clone = ir switch
|
||||||
|
{
|
||||||
|
RegexFindComplexIR find => new RegexFindComplexIR(find.IsNearest, find.CommandCount)
|
||||||
|
{
|
||||||
|
IsFullyOptimized = find.IsFullyOptimized
|
||||||
|
},
|
||||||
|
RegexFindSeqIR find => new RegexFindSeqIR(find.Pattern, find.IsFirst),
|
||||||
|
RegexMatchSeqIR match => new RegexMatchSeqIR(match.Pattern),
|
||||||
|
RegexMatchSetIR match => new RegexMatchSetIR(match.Charset),
|
||||||
|
RegexConditionIR condition => new RegexConditionIR(condition.SuccessCase, condition.FailCase),
|
||||||
|
RegexPackIR pack => new RegexPackIR(pack.Condition, pack.GroupName),
|
||||||
|
RegexCountComplexIR count => new RegexCountComplexIR(count.Min, count.Max, count.IsGreedy, count.CommandCount)
|
||||||
|
{
|
||||||
|
IsFullyOptimized = count.IsFullyOptimized
|
||||||
|
},
|
||||||
|
RegexCountSeqIR count => new RegexCountSeqIR(count.Min, count.Max, count.IsGreedy, count.Sequence),
|
||||||
|
RegexCountSetIR count => new RegexCountSetIR(count.Min, count.Max, count.IsGreedy, count.CharSet),
|
||||||
|
RegexTryIR tryIR => new RegexTryIR(tryIR.CommandCount)
|
||||||
|
{
|
||||||
|
IsFullyOptimized = tryIR.IsFullyOptimized
|
||||||
|
},
|
||||||
|
RegexPopIR pop => new RegexPopIR(pop.IsSuccess),
|
||||||
|
_ => throw new NotSupportedException($"Unsupported IR type: {ir.GetType().Name}")
|
||||||
|
};
|
||||||
|
|
||||||
|
clone.Prefix = new RegexIRPrefix(
|
||||||
|
ir.Prefix.WorkingRegion == 0 ? currentRegion : ir.Prefix.WorkingRegion,
|
||||||
|
ir.Prefix.Mask,
|
||||||
|
ir.Prefix.ObserveSource);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// file="RegexAnalyzer"
|
// file="RegexAnalyzerFrontEnd"
|
||||||
// Project: StgSharp
|
// Project: StgSharp
|
||||||
// AuthorGroup: Nitload
|
// AuthorGroup: Nitload
|
||||||
// Copyright (c) Nitload. All rights reserved.
|
// Copyright (c) Nitload. All rights reserved.
|
||||||
@@ -29,6 +29,7 @@ using StgSharp.RegularAnalysis.Abstraction;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -76,18 +77,35 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
{
|
{
|
||||||
// RegexAnalyzer interpreter = new();
|
// RegexAnalyzer interpreter = new();
|
||||||
// interpreter._source = regex;
|
// interpreter._source = regex;
|
||||||
|
AbstractSyntaxTree<RegexAstNode, RegexElementLabel> tree;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AbstractSyntaxTree<RegexAstNode, RegexElementLabel> tree = GenerateAST(regex);
|
tree = GenerateAST(regex);
|
||||||
OptimizeTree(tree);
|
OptimizeTree(tree);
|
||||||
List<RegexIR> base_ir = GenerateIR(tree);
|
|
||||||
ScanAndOptimizeIR(base_ir, out List<RegexIR> opt_ir);
|
|
||||||
return new TextRegexSource(regex, tree, base_ir, opt_ir);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return new TextRegexSource(regex, null, null, null, ex);
|
return new TextRegexSource(regex, null, null, null, ex);
|
||||||
}
|
}
|
||||||
|
List<RegexIR> base_ir;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
base_ir = GenerateIR(tree);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new TextRegexSource(regex, tree, null, null, ex);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ScanAndOptimizeIR(base_ir, out List<RegexIR> opt_ir);
|
||||||
|
List<RegexIR> prefix_ir = EmitPrefix(opt_ir);
|
||||||
|
return new TextRegexSource(regex, tree, base_ir, prefix_ir);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new TextRegexSource(regex, tree, base_ir, null, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// file="RegexIR.Prefix"
|
||||||
|
// 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.Text
|
||||||
|
{
|
||||||
|
internal enum RegexIRPrefixMask
|
||||||
|
{
|
||||||
|
|
||||||
|
Prev_Success = 1 << 0,
|
||||||
|
Prev_Fail = 1 << 1,
|
||||||
|
Always = 1 << 2,
|
||||||
|
ExeCondition = Prev_Fail | Prev_Success | Always,
|
||||||
|
Pop_Fail = 1 << 3,
|
||||||
|
Pop_Success = 1 << 4,
|
||||||
|
PopCondition = Pop_Success | Pop_Fail,
|
||||||
|
Observe_Line = 1 << 5,
|
||||||
|
Observe_Region = 1 << 6,
|
||||||
|
ObserveMethod = Observe_Line | Observe_Region
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal record struct RegexIRPrefix(
|
||||||
|
int WorkingRegion,
|
||||||
|
RegexIRPrefixMask Mask,
|
||||||
|
int ObserveSource
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{WorkingRegion:D4}, {DisplayMask(Mask , RegexIRPrefixMask.ExeCondition):D1}, {DisplayMask(Mask , RegexIRPrefixMask.PopCondition):D1}, {DisplayMask(Mask ,RegexIRPrefixMask.ObserveMethod):D1}, {ObserveSource:D4}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private int DisplayMask(
|
||||||
|
RegexIRPrefixMask mask,
|
||||||
|
RegexIRPrefixMask range
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return range switch
|
||||||
|
{
|
||||||
|
RegexIRPrefixMask.ExeCondition => (int)(mask & RegexIRPrefixMask.ExeCondition) >> 0,
|
||||||
|
RegexIRPrefixMask.PopCondition => (int)(mask & RegexIRPrefixMask.PopCondition) >> 3,
|
||||||
|
RegexIRPrefixMask.ObserveMethod => (int)(mask & RegexIRPrefixMask.ObserveMethod) >> 5,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(range), range, null)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
//
|
//
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -55,19 +56,6 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum RegexIRPrefix
|
|
||||||
{
|
|
||||||
|
|
||||||
Prev_Success = 1 << 0,
|
|
||||||
Prev_Fail = 1 << 1,
|
|
||||||
Always = 1 << 2,
|
|
||||||
ExeCondition = Prev_Fail | Prev_Success | Always,
|
|
||||||
Pop_Fail = 1 << 3,
|
|
||||||
Pop_Success = 1 << 4,
|
|
||||||
Pop_Condition = Pop_Success | Pop_Fail,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal interface IRegexComplex
|
internal interface IRegexComplex
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -92,7 +80,10 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexFindComplexIR(bool nearest, int count) : RegexIR, IRegexComplex
|
internal sealed class RegexFindComplexIR(
|
||||||
|
bool nearest,
|
||||||
|
int count
|
||||||
|
) : RegexIR, IRegexComplex
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsFullyOptimized { get; set; }
|
public bool IsFullyOptimized { get; set; }
|
||||||
@@ -103,9 +94,11 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Find_Complex;
|
internal override RegexIRCommand Command => RegexIRCommand.Find_Complex;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t FIND_COMPLEX {(IsNearest ? "NEAREST" : "FURTHEST")} COUNT: {CommandCount}";
|
return $"FIND_COMPLEX {(IsNearest ? "NEAREST" : "FURTHEST")} COUNT: {CommandCount}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -113,13 +106,25 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
internal abstract class RegexIR
|
internal abstract class RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public RegexIRPrefix Prefix { get; set; }
|
||||||
|
|
||||||
internal abstract RegexIRCommand Command { get; }
|
internal abstract RegexIRCommand Command { get; }
|
||||||
|
|
||||||
internal abstract string AsCommand(int lineNum);
|
internal string AsCommand(
|
||||||
|
int lineNum
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return $"[{lineNum}]\t{Prefix}\t{AsCommand()}";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract string AsCommand();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexFindSeqIR(string pattern, bool isFirst) : RegexIR
|
internal sealed class RegexFindSeqIR(
|
||||||
|
string pattern,
|
||||||
|
bool isFirst
|
||||||
|
) : RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsFirst { get; } = isFirst;
|
public bool IsFirst { get; } = isFirst;
|
||||||
@@ -128,9 +133,10 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Find_Seq;
|
internal override RegexIRCommand Command => RegexIRCommand.Find_Seq;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t FIND_SEQ \"{(string.IsNullOrEmpty(Pattern) ? "<EPSILON>" : Pattern)}\"";
|
return $"FIND_SEQ \"{(string.IsNullOrEmpty(Pattern) ? "<EPSILON>" : Pattern)}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -138,35 +144,46 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for a certain string pattern or charset from current position.
|
/// Searches for a certain string pattern or charset from current position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed class RegexMatchSeqIR(string pattern) : RegexIR
|
internal sealed class RegexMatchSeqIR(
|
||||||
|
string pattern
|
||||||
|
) : RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
public string Pattern { get; } = pattern;
|
public string Pattern { get; } = pattern;
|
||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Match_Seq;
|
internal override RegexIRCommand Command => RegexIRCommand.Match_Seq;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t MATCH_SEQ \"{(string.IsNullOrEmpty(Pattern) ? "<EPSILON>" : Pattern)}\"";
|
return $"MATCH_SEQ \"{(string.IsNullOrEmpty(Pattern) ? "<EPSILON>" : Pattern)}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexMatchSetIR(string charset) : RegexIR
|
internal sealed class RegexMatchSetIR(
|
||||||
|
string charset
|
||||||
|
) : RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
public string Charset { get; } = charset;
|
public string Charset { get; } = charset;
|
||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Match_Set;
|
internal override RegexIRCommand Command => RegexIRCommand.Match_Set;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t MATCH_SET \"{Charset}\"";
|
return $"MATCH_SET \"{Charset}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexConditionIR(int success, int fail) : RegexIR
|
internal sealed class RegexConditionIR(
|
||||||
|
int success,
|
||||||
|
int fail
|
||||||
|
) : RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
public int SuccessCase { get; } = success;
|
public int SuccessCase { get; } = success;
|
||||||
@@ -175,14 +192,19 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Condition;
|
internal override RegexIRCommand Command => RegexIRCommand.Condition;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t CONDITION SUCCESS: {SuccessCase} FAIL: {FailCase}";
|
return $"CONDITION SUCCESS: {SuccessCase} FAIL: {FailCase}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexPackIR(bool condition, string name = "") : RegexIR
|
internal sealed class RegexPackIR(
|
||||||
|
bool condition,
|
||||||
|
string name = ""
|
||||||
|
) : RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool Condition { get; } = condition;
|
public bool Condition { get; } = condition;
|
||||||
@@ -191,14 +213,21 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Pack;
|
internal override RegexIRCommand Command => RegexIRCommand.Pack;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t PACK {(Condition ? "SUCCESS" : "FAIL")} GROUP: \"{GroupName}\"";
|
return $"PACK {(Condition ? "SUCCESS" : "FAIL")} GROUP: \"{GroupName}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexCountComplexIR(int min, int max, bool isGreedy, int operation) : RegexIR, IRegexCount, IRegexComplex
|
internal sealed class RegexCountComplexIR(
|
||||||
|
int min,
|
||||||
|
int max,
|
||||||
|
bool isGreedy,
|
||||||
|
int operation
|
||||||
|
) : RegexIR, IRegexCount, IRegexComplex
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsGreedy { get; } = isGreedy;
|
public bool IsGreedy { get; } = isGreedy;
|
||||||
@@ -217,14 +246,21 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command { get; } = RegexIRCommand.Count_Complex;
|
internal override RegexIRCommand Command { get; } = RegexIRCommand.Count_Complex;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t COUNT {(IsGreedy ? "GREEDY" : "NON_GREEDY")} MIN: {Min} MAX: {Max} OPERATION: {CommandCount}";
|
return $"COUNT {(IsGreedy ? "GREEDY" : "NON_GREEDY")} MIN: {Min} MAX: {Max} OPERATION: {CommandCount}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexCountSeqIR(int min, int max, bool isGreedy, string seq) : RegexIR, IRegexCount
|
internal sealed class RegexCountSeqIR(
|
||||||
|
int min,
|
||||||
|
int max,
|
||||||
|
bool isGreedy,
|
||||||
|
string seq
|
||||||
|
) : RegexIR, IRegexCount
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsGreedy { get; } = isGreedy;
|
public bool IsGreedy { get; } = isGreedy;
|
||||||
@@ -241,14 +277,21 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command { get; } = RegexIRCommand.Count_Seq;
|
internal override RegexIRCommand Command { get; } = RegexIRCommand.Count_Seq;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t COUNT_SEQ {(IsGreedy ? "GREEDY" : "NON_GREEDY")} MIN: {Min} MAX: {Max} SEQ: \"{Sequence}\"";
|
return $"COUNT_SEQ {(IsGreedy ? "GREEDY" : "NON_GREEDY")} MIN: {Min} MAX: {Max} SEQ: \"{Sequence}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexCountSetIR(int min, int max, bool isGreedy, string set) : RegexIR, IRegexCount
|
internal sealed class RegexCountSetIR(
|
||||||
|
int min,
|
||||||
|
int max,
|
||||||
|
bool isGreedy,
|
||||||
|
string set
|
||||||
|
) : RegexIR, IRegexCount
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsGreedy { get; } = isGreedy;
|
public bool IsGreedy { get; } = isGreedy;
|
||||||
@@ -267,14 +310,18 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Count_Set;
|
internal override RegexIRCommand Command => RegexIRCommand.Count_Set;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t COUNT_SET {(IsGreedy ? "GREEDY" : "NON_GREEDY")} MIN: {Min} MAX: {Max} SET: \"{CharSet}\"";
|
return $"COUNT_SET {(IsGreedy ? "GREEDY" : "NON_GREEDY")} MIN: {Min} MAX: {Max} SET: \"{CharSet}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexTryIR(int count) : RegexIR, IRegexComplex
|
internal sealed class RegexTryIR(
|
||||||
|
int count
|
||||||
|
) : RegexIR, IRegexComplex
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsFullyOptimized { get; set; }
|
public bool IsFullyOptimized { get; set; }
|
||||||
@@ -283,23 +330,29 @@ namespace StgSharp.RegularAnalysis.Text
|
|||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Try;
|
internal override RegexIRCommand Command => RegexIRCommand.Try;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t TRY {CommandCount}";
|
return $"TRY {CommandCount}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RegexPopIR(bool isSuccess) : RegexIR
|
internal sealed class RegexPopIR(
|
||||||
|
bool isSuccess
|
||||||
|
) : RegexIR
|
||||||
{
|
{
|
||||||
|
|
||||||
public bool IsSuccess { get; } = isSuccess;
|
public bool IsSuccess { get; } = isSuccess;
|
||||||
|
|
||||||
internal override RegexIRCommand Command => RegexIRCommand.Pop;
|
internal override RegexIRCommand Command => RegexIRCommand.Pop;
|
||||||
|
|
||||||
internal override string AsCommand(int lineNum)
|
protected override string AsCommand(
|
||||||
|
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return $"[{lineNum}]\t POP {(IsSuccess ? "SUCCESS" : "FAIL")}";
|
return $"POP {(IsSuccess ? "SUCCESS" : "FAIL")}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ namespace StgSharp
|
|||||||
|
|
||||||
private static string[] regexSource = [
|
private static string[] regexSource = [
|
||||||
@"[.]*",
|
@"[.]*",
|
||||||
/*
|
/**/
|
||||||
@"http|https|ftp|ftps",
|
@"http|https|ftp|ftps",
|
||||||
@"abc[0-9]x|abc[0-9]y|abd[0-9]x|abd[0-9]y|xyz",
|
@"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",
|
@"get_name|get_value|get_type|set_name|set_value|set_type",
|
||||||
@"helix|hello|help|hero|hers|her",
|
@"helix|hello|help|hero|hers|her",
|
||||||
@"a*.[abc]*(abcd|a(bc)c)+(?<name>.*)234"
|
@"a*.[abc]*(?<a>abcd|a(bc)c)(?<name>.*)234"
|
||||||
/**/
|
/**/
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -75,6 +75,7 @@ namespace StgSharp
|
|||||||
Console.WriteLine(opt_ir[i].AsCommand(i));
|
Console.WriteLine(opt_ir[i].AsCommand(i));
|
||||||
}
|
}
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
Console.WriteLine(interpreterSource.AnalyseException);
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,453 @@
|
|||||||
|
result of "[.]*"
|
||||||
|
| * COUNT
|
||||||
|
|| [.] UNIT_SET
|
||||||
|
-----IR-----
|
||||||
|
[0] 0000,0,0,0,0000 COUNT_SET GREEDY MIN: 0 MAX: -1 SET: "[.]"
|
||||||
|
-----Optimized once-----
|
||||||
|
[0] 0000,0,0,0,0000 COUNT_SET GREEDY MIN: 0 MAX: -1 SET: "[.]"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result of "http|https|ftp|ftps"
|
||||||
|
| ALT
|
||||||
|
|| CONCAT
|
||||||
|
||| http UNIT_SPAN
|
||||||
|
||| ALT
|
||||||
|
|||| UNIT
|
||||||
|
|||| s UNIT
|
||||||
|
|| CONCAT
|
||||||
|
||| ftp UNIT_SPAN
|
||||||
|
||| ALT
|
||||||
|
|||| UNIT
|
||||||
|
|||| s UNIT
|
||||||
|
-----IR-----
|
||||||
|
[0] 0000,0,0,0,0000 TRY 10
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SEQ "http"
|
||||||
|
[2] 0000,0,0,0,0000 TRY 1
|
||||||
|
[3] 0000,0,0,0,0000 MATCH_SEQ "<EPSILON>"
|
||||||
|
[4] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[5] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[6] 0000,0,0,0,0000 TRY 1
|
||||||
|
[7] 0000,0,0,0,0000 MATCH_SEQ "s"
|
||||||
|
[8] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[9] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[10] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[11] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[12] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[13] 0000,0,0,0,0000 TRY 10
|
||||||
|
[14] 0000,0,0,0,0000 MATCH_SEQ "ftp"
|
||||||
|
[15] 0000,0,0,0,0000 TRY 1
|
||||||
|
[16] 0000,0,0,0,0000 MATCH_SEQ "<EPSILON>"
|
||||||
|
[17] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[18] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[19] 0000,0,0,0,0000 TRY 1
|
||||||
|
[20] 0000,0,0,0,0000 MATCH_SEQ "s"
|
||||||
|
[21] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[22] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[23] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[24] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[25] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[26] 0000,0,0,0,0000 POP FAIL
|
||||||
|
-----Optimized once-----
|
||||||
|
[0] 0000,0,0,0,0000 TRY 10
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SEQ "http"
|
||||||
|
[2] 0000,0,0,0,0000 TRY 1
|
||||||
|
[3] 0000,0,0,0,0000 MATCH_SEQ "<EPSILON>"
|
||||||
|
[4] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[5] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[6] 0000,0,0,0,0000 TRY 1
|
||||||
|
[7] 0000,0,0,0,0000 MATCH_SEQ "s"
|
||||||
|
[8] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[9] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[10] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[11] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[12] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[13] 0000,0,0,0,0000 TRY 10
|
||||||
|
[14] 0000,0,0,0,0000 MATCH_SEQ "ftp"
|
||||||
|
[15] 0000,0,0,0,0000 TRY 1
|
||||||
|
[16] 0000,0,0,0,0000 MATCH_SEQ "<EPSILON>"
|
||||||
|
[17] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[18] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[19] 0000,0,0,0,0000 TRY 1
|
||||||
|
[20] 0000,0,0,0,0000 MATCH_SEQ "s"
|
||||||
|
[21] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[22] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[23] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[24] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[25] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[26] 0000,0,0,0,0000 POP FAIL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result of "abc[0-9]x|abc[0-9]y|abd[0-9]x|abd[0-9]y|xyz"
|
||||||
|
| ALT
|
||||||
|
|| CONCAT
|
||||||
|
||| ab UNIT_SPAN
|
||||||
|
||| ALT
|
||||||
|
|||| CONCAT
|
||||||
|
||||| c UNIT
|
||||||
|
||||| CONCAT
|
||||||
|
|||||| [0-9] UNIT_SET
|
||||||
|
|||||| ALT
|
||||||
|
||||||| x UNIT
|
||||||
|
||||||| y UNIT
|
||||||
|
|||| CONCAT
|
||||||
|
||||| d UNIT
|
||||||
|
||||| CONCAT
|
||||||
|
|||||| [0-9] UNIT_SET
|
||||||
|
|||||| ALT
|
||||||
|
||||||| x UNIT
|
||||||
|
||||||| y UNIT
|
||||||
|
|| CONCAT
|
||||||
|
||| xyz UNIT_SPAN
|
||||||
|
-----IR-----
|
||||||
|
[0] 0000,0,0,0,0000 TRY 30
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SEQ "ab"
|
||||||
|
[2] 0000,0,0,0,0000 TRY 11
|
||||||
|
[3] 0000,0,0,0,0000 MATCH_SEQ "c"
|
||||||
|
[4] 0000,0,0,0,0000 MATCH_SET "[0-9]"
|
||||||
|
[5] 0000,0,0,0,0000 TRY 1
|
||||||
|
[6] 0000,0,0,0,0000 MATCH_SEQ "x"
|
||||||
|
[7] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[8] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[9] 0000,0,0,0,0000 TRY 1
|
||||||
|
[10] 0000,0,0,0,0000 MATCH_SEQ "y"
|
||||||
|
[11] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[12] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[13] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[14] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[15] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[16] 0000,0,0,0,0000 TRY 11
|
||||||
|
[17] 0000,0,0,0,0000 MATCH_SEQ "d"
|
||||||
|
[18] 0000,0,0,0,0000 MATCH_SET "[0-9]"
|
||||||
|
[19] 0000,0,0,0,0000 TRY 1
|
||||||
|
[20] 0000,0,0,0,0000 MATCH_SEQ "x"
|
||||||
|
[21] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[22] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[23] 0000,0,0,0,0000 TRY 1
|
||||||
|
[24] 0000,0,0,0,0000 MATCH_SEQ "y"
|
||||||
|
[25] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[26] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[27] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[28] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[29] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[30] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[31] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[32] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[33] 0000,0,0,0,0000 TRY 1
|
||||||
|
[34] 0000,0,0,0,0000 MATCH_SEQ "xyz"
|
||||||
|
[35] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[36] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[37] 0000,0,0,0,0000 POP FAIL
|
||||||
|
-----Optimized once-----
|
||||||
|
[0] 0000,0,0,0,0000 TRY 30
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SEQ "ab"
|
||||||
|
[2] 0000,0,0,0,0000 TRY 11
|
||||||
|
[3] 0000,0,0,0,0000 MATCH_SEQ "c"
|
||||||
|
[4] 0000,0,0,0,0000 MATCH_SET "[0-9]"
|
||||||
|
[5] 0000,0,0,0,0000 TRY 1
|
||||||
|
[6] 0000,0,0,0,0000 MATCH_SEQ "x"
|
||||||
|
[7] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[8] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[9] 0000,0,0,0,0000 TRY 1
|
||||||
|
[10] 0000,0,0,0,0000 MATCH_SEQ "y"
|
||||||
|
[11] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[12] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[13] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[14] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[15] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[16] 0000,0,0,0,0000 TRY 11
|
||||||
|
[17] 0000,0,0,0,0000 MATCH_SEQ "d"
|
||||||
|
[18] 0000,0,0,0,0000 MATCH_SET "[0-9]"
|
||||||
|
[19] 0000,0,0,0,0000 TRY 1
|
||||||
|
[20] 0000,0,0,0,0000 MATCH_SEQ "x"
|
||||||
|
[21] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[22] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[23] 0000,0,0,0,0000 TRY 1
|
||||||
|
[24] 0000,0,0,0,0000 MATCH_SEQ "y"
|
||||||
|
[25] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[26] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[27] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[28] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[29] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[30] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[31] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[32] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[33] 0000,0,0,0,0000 TRY 1
|
||||||
|
[34] 0000,0,0,0,0000 MATCH_SEQ "xyz"
|
||||||
|
[35] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[36] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[37] 0000,0,0,0,0000 POP FAIL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result of "get_name|get_value|get_type|set_name|set_value|set_type"
|
||||||
|
| ALT
|
||||||
|
|| CONCAT
|
||||||
|
||| get_ UNIT_SPAN
|
||||||
|
||| ALT
|
||||||
|
|||| CONCAT
|
||||||
|
||||| name UNIT_SPAN
|
||||||
|
|||| CONCAT
|
||||||
|
||||| value UNIT_SPAN
|
||||||
|
|||| CONCAT
|
||||||
|
||||| type UNIT_SPAN
|
||||||
|
|| CONCAT
|
||||||
|
||| set_ UNIT_SPAN
|
||||||
|
||| ALT
|
||||||
|
|||| CONCAT
|
||||||
|
||||| name UNIT_SPAN
|
||||||
|
|||| CONCAT
|
||||||
|
||||| value UNIT_SPAN
|
||||||
|
|||| CONCAT
|
||||||
|
||||| type UNIT_SPAN
|
||||||
|
-----IR-----
|
||||||
|
[0] 0000,0,0,0,0000 TRY 14
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SEQ "get_"
|
||||||
|
[2] 0000,0,0,0,0000 TRY 1
|
||||||
|
[3] 0000,0,0,0,0000 MATCH_SEQ "name"
|
||||||
|
[4] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[5] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[6] 0000,0,0,0,0000 TRY 1
|
||||||
|
[7] 0000,0,0,0,0000 MATCH_SEQ "value"
|
||||||
|
[8] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[9] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[10] 0000,0,0,0,0000 TRY 1
|
||||||
|
[11] 0000,0,0,0,0000 MATCH_SEQ "type"
|
||||||
|
[12] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[13] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[14] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[15] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[16] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[17] 0000,0,0,0,0000 TRY 14
|
||||||
|
[18] 0000,0,0,0,0000 MATCH_SEQ "set_"
|
||||||
|
[19] 0000,0,0,0,0000 TRY 1
|
||||||
|
[20] 0000,0,0,0,0000 MATCH_SEQ "name"
|
||||||
|
[21] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[22] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[23] 0000,0,0,0,0000 TRY 1
|
||||||
|
[24] 0000,0,0,0,0000 MATCH_SEQ "value"
|
||||||
|
[25] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[26] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[27] 0000,0,0,0,0000 TRY 1
|
||||||
|
[28] 0000,0,0,0,0000 MATCH_SEQ "type"
|
||||||
|
[29] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[30] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[31] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[32] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[33] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[34] 0000,0,0,0,0000 POP FAIL
|
||||||
|
-----Optimized once-----
|
||||||
|
[0] 0000,0,0,0,0000 TRY 14
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SEQ "get_"
|
||||||
|
[2] 0000,0,0,0,0000 TRY 1
|
||||||
|
[3] 0000,0,0,0,0000 MATCH_SEQ "name"
|
||||||
|
[4] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[5] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[6] 0000,0,0,0,0000 TRY 1
|
||||||
|
[7] 0000,0,0,0,0000 MATCH_SEQ "value"
|
||||||
|
[8] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[9] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[10] 0000,0,0,0,0000 TRY 1
|
||||||
|
[11] 0000,0,0,0,0000 MATCH_SEQ "type"
|
||||||
|
[12] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[13] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[14] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[15] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[16] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[17] 0000,0,0,0,0000 TRY 14
|
||||||
|
[18] 0000,0,0,0,0000 MATCH_SEQ "set_"
|
||||||
|
[19] 0000,0,0,0,0000 TRY 1
|
||||||
|
[20] 0000,0,0,0,0000 MATCH_SEQ "name"
|
||||||
|
[21] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[22] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[23] 0000,0,0,0,0000 TRY 1
|
||||||
|
[24] 0000,0,0,0,0000 MATCH_SEQ "value"
|
||||||
|
[25] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[26] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[27] 0000,0,0,0,0000 TRY 1
|
||||||
|
[28] 0000,0,0,0,0000 MATCH_SEQ "type"
|
||||||
|
[29] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[30] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[31] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[32] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[33] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[34] 0000,0,0,0,0000 POP FAIL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result of "helix|hello|help|hero|hers|her"
|
||||||
|
| CONCAT
|
||||||
|
|| he UNIT_SPAN
|
||||||
|
|| ALT
|
||||||
|
||| CONCAT
|
||||||
|
|||| l UNIT
|
||||||
|
|||| ALT
|
||||||
|
||||| CONCAT
|
||||||
|
|||||| ix UNIT_SPAN
|
||||||
|
||||| CONCAT
|
||||||
|
|||||| lo UNIT_SPAN
|
||||||
|
||||| p UNIT
|
||||||
|
||| CONCAT
|
||||||
|
|||| r UNIT
|
||||||
|
|||| ALT
|
||||||
|
||||| o UNIT
|
||||||
|
||||| s UNIT
|
||||||
|
||||| UNIT
|
||||||
|
-----IR-----
|
||||||
|
[0] 0000,0,0,0,0000 MATCH_SEQ "he"
|
||||||
|
[1] 0000,0,0,0,0000 TRY 14
|
||||||
|
[2] 0000,0,0,0,0000 MATCH_SEQ "l"
|
||||||
|
[3] 0000,0,0,0,0000 TRY 1
|
||||||
|
[4] 0000,0,0,0,0000 MATCH_SEQ "ix"
|
||||||
|
[5] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[6] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[7] 0000,0,0,0,0000 TRY 1
|
||||||
|
[8] 0000,0,0,0,0000 MATCH_SEQ "lo"
|
||||||
|
[9] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[10] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[11] 0000,0,0,0,0000 TRY 1
|
||||||
|
[12] 0000,0,0,0,0000 MATCH_SEQ "p"
|
||||||
|
[13] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[14] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[15] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[16] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[17] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[18] 0000,0,0,0,0000 TRY 14
|
||||||
|
[19] 0000,0,0,0,0000 MATCH_SEQ "r"
|
||||||
|
[20] 0000,0,0,0,0000 TRY 1
|
||||||
|
[21] 0000,0,0,0,0000 MATCH_SEQ "o"
|
||||||
|
[22] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[23] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[24] 0000,0,0,0,0000 TRY 1
|
||||||
|
[25] 0000,0,0,0,0000 MATCH_SEQ "s"
|
||||||
|
[26] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[27] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[28] 0000,0,0,0,0000 TRY 1
|
||||||
|
[29] 0000,0,0,0,0000 MATCH_SEQ "<EPSILON>"
|
||||||
|
[30] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[31] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[32] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[33] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[34] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[35] 0000,0,0,0,0000 POP FAIL
|
||||||
|
-----Optimized once-----
|
||||||
|
[0] 0000,0,0,0,0000 MATCH_SEQ "he"
|
||||||
|
[1] 0000,0,0,0,0000 TRY 14
|
||||||
|
[2] 0000,0,0,0,0000 MATCH_SEQ "l"
|
||||||
|
[3] 0000,0,0,0,0000 TRY 1
|
||||||
|
[4] 0000,0,0,0,0000 MATCH_SEQ "ix"
|
||||||
|
[5] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[6] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[7] 0000,0,0,0,0000 TRY 1
|
||||||
|
[8] 0000,0,0,0,0000 MATCH_SEQ "lo"
|
||||||
|
[9] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[10] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[11] 0000,0,0,0,0000 TRY 1
|
||||||
|
[12] 0000,0,0,0,0000 MATCH_SEQ "p"
|
||||||
|
[13] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[14] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[15] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[16] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[17] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[18] 0000,0,0,0,0000 TRY 14
|
||||||
|
[19] 0000,0,0,0,0000 MATCH_SEQ "r"
|
||||||
|
[20] 0000,0,0,0,0000 TRY 1
|
||||||
|
[21] 0000,0,0,0,0000 MATCH_SEQ "o"
|
||||||
|
[22] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[23] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[24] 0000,0,0,0,0000 TRY 1
|
||||||
|
[25] 0000,0,0,0,0000 MATCH_SEQ "s"
|
||||||
|
[26] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[27] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[28] 0000,0,0,0,0000 TRY 1
|
||||||
|
[29] 0000,0,0,0,0000 MATCH_SEQ "<EPSILON>"
|
||||||
|
[30] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[31] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[32] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[33] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[34] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[35] 0000,0,0,0,0000 POP FAIL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
result of "a*.[abc]*(?<a>abcd|a(bc)c)(?<name>.*)234"
|
||||||
|
| CONCAT
|
||||||
|
|| * COUNT
|
||||||
|
||| a UNIT
|
||||||
|
|| CONCAT
|
||||||
|
||| . UNIT_SET
|
||||||
|
||| CONCAT
|
||||||
|
|||| * COUNT
|
||||||
|
||||| [abc] UNIT_SET
|
||||||
|
|||| CONCAT
|
||||||
|
||||| (?<a> GROUP_BEGIN
|
||||||
|
|||||| CONCAT
|
||||||
|
||||||| abc UNIT_SPAN
|
||||||
|
||||||| ALT
|
||||||
|
|||||||| d UNIT
|
||||||
|
|||||||| c UNIT
|
||||||
|
||||| CONCAT
|
||||||
|
|||||| (?<name> GROUP_BEGIN
|
||||||
|
||||||| * COUNT
|
||||||
|
|||||||| . UNIT_SET
|
||||||
|
|||||| CONCAT
|
||||||
|
||||||| 234 UNIT_SPAN
|
||||||
|
-----IR-----
|
||||||
|
[0] 0000,0,0,0,0000 COUNT_SEQ GREEDY MIN: 0 MAX: -1 SEQ: "a"
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SET "."
|
||||||
|
[2] 0000,0,0,0,0000 COUNT_SET GREEDY MIN: 0 MAX: -1 SET: "[abc]"
|
||||||
|
[3] 0000,0,0,0,0000 TRY 10
|
||||||
|
[4] 0000,0,0,0,0000 MATCH_SEQ "abc"
|
||||||
|
[5] 0000,0,0,0,0000 TRY 1
|
||||||
|
[6] 0000,0,0,0,0000 MATCH_SEQ "d"
|
||||||
|
[7] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[8] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[9] 0000,0,0,0,0000 TRY 1
|
||||||
|
[10] 0000,0,0,0,0000 MATCH_SEQ "c"
|
||||||
|
[11] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[12] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[13] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[14] 0000,0,0,0,0000 CONDITION SUCCESS: 2 FAIL: 1
|
||||||
|
[15] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[16] 0000,0,0,0,0000 PACK SUCCESS GROUP: "a"
|
||||||
|
[17] 0000,0,0,0,0000 TRY 1
|
||||||
|
[18] 0000,0,0,0,0000 COUNT_SET GREEDY MIN: 0 MAX: -1 SET: "."
|
||||||
|
[19] 0000,0,0,0,0000 CONDITION SUCCESS: 2 FAIL: 1
|
||||||
|
[20] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[21] 0000,0,0,0,0000 PACK SUCCESS GROUP: "name"
|
||||||
|
[22] 0000,0,0,0,0000 MATCH_SEQ "234"
|
||||||
|
-----Optimized once-----
|
||||||
|
[0] 0000,0,0,0,0000 COUNT_SEQ GREEDY MIN: 0 MAX: -1 SEQ: "a"
|
||||||
|
[1] 0000,0,0,0,0000 MATCH_SET "."
|
||||||
|
[2] 0000,0,0,0,0000 COUNT_SET GREEDY MIN: 0 MAX: -1 SET: "[abc]"
|
||||||
|
[3] 0000,0,0,0,0000 TRY 10
|
||||||
|
[4] 0000,0,0,0,0000 MATCH_SEQ "abc"
|
||||||
|
[5] 0000,0,0,0,0000 TRY 1
|
||||||
|
[6] 0000,0,0,0,0000 MATCH_SEQ "d"
|
||||||
|
[7] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[8] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[9] 0000,0,0,0,0000 TRY 1
|
||||||
|
[10] 0000,0,0,0,0000 MATCH_SEQ "c"
|
||||||
|
[11] 0000,0,0,0,0000 CONDITION SUCCESS: 1 FAIL: 2
|
||||||
|
[12] 0000,0,0,0,0000 POP SUCCESS
|
||||||
|
[13] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[14] 0000,0,0,0,0000 CONDITION SUCCESS: 2 FAIL: 1
|
||||||
|
[15] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[16] 0000,0,0,0,0000 PACK SUCCESS GROUP: "a"
|
||||||
|
[17] 0000,0,0,0,0000 TRY 1
|
||||||
|
[18] 0000,0,0,0,0000 FIND_COMPLEX FURTHEST COUNT: -1
|
||||||
|
[19] 0000,0,0,0,0000 CONDITION SUCCESS: 2 FAIL: 1
|
||||||
|
[20] 0000,0,0,0,0000 POP FAIL
|
||||||
|
[21] 0000,0,0,0,0000 PACK SUCCESS GROUP: "name"
|
||||||
|
[22] 0000,0,0,0,0000 MATCH_SEQ "234"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Program has exited with no error, press any key to exit.
|
||||||
Reference in New Issue
Block a user