use new exit lable
This commit is contained in:
@@ -17,7 +17,8 @@ namespace Nitload.RegularAnalysis.Text
|
||||
in SequenceEmitter<string> sc,
|
||||
in List<SequenceEmitter<string>> func_list,
|
||||
in SourceGenContext context,
|
||||
in ExitLabel exit_label
|
||||
in ExitLabel local_fail,
|
||||
ref ExitLabel backtrack
|
||||
)
|
||||
{
|
||||
// A special rule owns the entire matched subtree. Returning false leaves emission
|
||||
@@ -25,7 +26,7 @@ namespace Nitload.RegularAnalysis.Text
|
||||
return node.Label switch
|
||||
{
|
||||
RegexElementLabel.CONCAT => TryGenerateFindConcat(node, sc, func_list, context,
|
||||
exit_label),
|
||||
local_fail, ref backtrack),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
@@ -166,10 +167,12 @@ namespace Nitload.RegularAnalysis.Text
|
||||
in ExitLabel success
|
||||
)
|
||||
{
|
||||
ExitLabel failure = context.RequestExitLabel(ExitMode.Goto);
|
||||
ExitLabel failure = context.RequestExitLabel(ExitKind.AltNext);
|
||||
string entry = $"__alt_entry_{context.RequestScratchScopeIndex()}";
|
||||
_ = sc.AppendLine($"{ROS_char} {entry} = {context.RemainSpan};");
|
||||
GenerateMethodSource(node, sc, func_list, context, failure);
|
||||
// Keep branch-local retries isolated from both siblings and the caller's path.
|
||||
ExitLabel branch_backtrack = failure;
|
||||
GenerateMethodSource(node, sc, func_list, context, failure, ref branch_backtrack);
|
||||
_ = sc.AppendLine($"goto {success.GetLabelName()};")
|
||||
.AppendLine($"{failure.GetLabelName()}:")
|
||||
.AppendLine($"{context.RemainSpan} = {entry};");
|
||||
@@ -180,50 +183,6 @@ namespace Nitload.RegularAnalysis.Text
|
||||
|
||||
#endregion
|
||||
|
||||
#region CONCAT continuation
|
||||
|
||||
private static void AppendConcatNodes(
|
||||
RegexAstNode node,
|
||||
List<RegexAstNode> sequence
|
||||
)
|
||||
{
|
||||
if (RegexAstNode.IsNullOrEmpty(node)) {
|
||||
return;
|
||||
}
|
||||
if (node.Label == RegexElementLabel.CONCAT &&
|
||||
!RegexAstNode.IsDotStar(node.Left) && !IsNamedFind(node))
|
||||
{
|
||||
AppendConcatNodes(node.Left, sequence);
|
||||
AppendConcatNodes(node.Right, sequence);
|
||||
} else {
|
||||
sequence.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateConcatTail(
|
||||
IReadOnlyList<RegexAstNode> sequence,
|
||||
int start,
|
||||
in SequenceEmitter<string> sc,
|
||||
in List<SequenceEmitter<string>> func_list,
|
||||
in SourceGenContext context,
|
||||
in ExitLabel exit_label
|
||||
)
|
||||
{
|
||||
for (int i = start; i < sequence.Count; i++)
|
||||
{
|
||||
RegexAstNode node = sequence[i];
|
||||
if (node.Label == RegexElementLabel.COUNT)
|
||||
{
|
||||
// COUNT owns both its repetition and the continuation that may retry it.
|
||||
GenerateCount(node, sc, func_list, context, exit_label, sequence, i + 1);
|
||||
return;
|
||||
}
|
||||
GenerateMethodSource(node, sc, func_list, context, exit_label);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FIND concatenation
|
||||
|
||||
private static bool TryGenerateFindConcat(
|
||||
@@ -231,7 +190,8 @@ namespace Nitload.RegularAnalysis.Text
|
||||
in SequenceEmitter<string> sc,
|
||||
in List<SequenceEmitter<string>> func_list,
|
||||
in SourceGenContext context,
|
||||
in ExitLabel exit_label
|
||||
in ExitLabel local_fail,
|
||||
ref ExitLabel backtrack
|
||||
)
|
||||
{
|
||||
RegexAstNode left = node.Left;
|
||||
@@ -246,7 +206,7 @@ namespace Nitload.RegularAnalysis.Text
|
||||
{
|
||||
// TODO(NGRA): Emit the unnamed FIND candidate loop and retry the right subtree
|
||||
// until it succeeds or no anchor candidate remains.
|
||||
GenerateMethodSource(right, sc, func_list, context, exit_label, true);
|
||||
GenerateMethodSource(right, sc, func_list, context, local_fail, ref backtrack, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -256,7 +216,7 @@ namespace Nitload.RegularAnalysis.Text
|
||||
{
|
||||
// TODO(NGRA): Emit named FIND retry and capture the text preceding the
|
||||
// successful anchor candidate.
|
||||
GenerateMethodSource(right, sc, func_list, context, exit_label, true);
|
||||
GenerateMethodSource(right, sc, func_list, context, local_fail, ref backtrack, true);
|
||||
} else
|
||||
{
|
||||
// TODO(NGRA): Capture the remaining input for a terminal named dot-star.
|
||||
|
||||
Reference in New Issue
Block a user