1365 references to RegexNodeKind
System.Text.RegularExpressions (1365)
System\Text\RegularExpressions\RegexCompiler.cs (144)
513if (RegexPrefixAnalyzer.FindTrailingAnchor(_regexTree.Root) == RegexNodeKind.End && 669case RegexNodeKind.Bol: 753case RegexNodeKind.End or RegexNodeKind.EndZ when _regexTree.FindOptimizations.MaxPossibleLength is int maxLength: 1274Debug.Assert(target.LoopNode.Kind is RegexNodeKind.Setloop or RegexNodeKind.Setlazy or RegexNodeKind.Setloopatomic); 1457Debug.Assert(node.Kind == RegexNodeKind.Capture, "Every generated tree should begin with a capture node"); 1467case RegexNodeKind.Multi or RegexNodeKind.Notone or RegexNodeKind.One or RegexNodeKind.Set: 1473int length = node.Kind == RegexNodeKind.Multi ? node.Str!.Length : 1; 1673Debug.Assert(node.Kind is RegexNodeKind.Alternate, $"Unexpected type: {node.Kind}"); 2033case RegexNodeKind.One: 2034case RegexNodeKind.Set: 2039case RegexNodeKind.Multi: 2045case RegexNodeKind.Concatenate when child.Child(0) == startingLiteralNode && (startingLiteralNode.Kind is RegexNodeKind.One or RegexNodeKind.Set or RegexNodeKind.Multi): 2055child.Child(0).Kind is RegexNodeKind.Multi ? 2057new RegexNode(RegexNodeKind.Empty, child.Options)); 2095Debug.Assert(multi.Kind is RegexNodeKind.Multi, $"Expected a Multi node, got {multi.Kind}"); 2097new(RegexNodeKind.One, multi.Options, multi.Str[1]) : 2098new(RegexNodeKind.Multi, multi.Options, multi.Str.Substring(1)); 2105Debug.Assert(node.Kind is RegexNodeKind.Backreference, $"Unexpected type: {node.Kind}"); 2295Debug.Assert(node.Kind is RegexNodeKind.BackreferenceConditional, $"Unexpected type: {node.Kind}"); 2309RegexNode? noBranch = node.Child(1) is { Kind: not RegexNodeKind.Empty } childNo ? childNo : null; 2454Debug.Assert(node.Kind is RegexNodeKind.ExpressionConditional, $"Unexpected type: {node.Kind}"); 2470RegexNode? noBranch = node.Child(2) is { Kind: not RegexNodeKind.Empty } childNo ? childNo : null; 2647Debug.Assert(node.Kind is RegexNodeKind.Capture, $"Unexpected type: {node.Kind}"); 2773Debug.Assert(node.Kind is RegexNodeKind.PositiveLookaround, $"Unexpected type: {node.Kind}"); 2817Debug.Assert(node.Kind is RegexNodeKind.NegativeLookaround, $"Unexpected type: {node.Kind}"); 2968case RegexNodeKind.Beginning: 2969case RegexNodeKind.Start: 2970case RegexNodeKind.Bol: 2971case RegexNodeKind.Eol: 2972case RegexNodeKind.End: 2973case RegexNodeKind.EndZ: 2977case RegexNodeKind.Boundary: 2978case RegexNodeKind.NonBoundary: 2979case RegexNodeKind.ECMABoundary: 2980case RegexNodeKind.NonECMABoundary: 2984case RegexNodeKind.Multi: 2988case RegexNodeKind.One: 2989case RegexNodeKind.Notone: 2990case RegexNodeKind.Set: 2994case RegexNodeKind.Oneloop: 2995case RegexNodeKind.Notoneloop: 2996case RegexNodeKind.Setloop: 3000case RegexNodeKind.Onelazy: 3001case RegexNodeKind.Notonelazy: 3002case RegexNodeKind.Setlazy: 3006case RegexNodeKind.Oneloopatomic: 3007case RegexNodeKind.Notoneloopatomic: 3008case RegexNodeKind.Setloopatomic: 3012case RegexNodeKind.Loop: 3016case RegexNodeKind.Lazyloop: 3020case RegexNodeKind.Alternate: 3024case RegexNodeKind.Concatenate: 3028case RegexNodeKind.Atomic: 3032case RegexNodeKind.Backreference: 3036case RegexNodeKind.BackreferenceConditional: 3040case RegexNodeKind.ExpressionConditional: 3044case RegexNodeKind.Capture: 3048case RegexNodeKind.PositiveLookaround: 3052case RegexNodeKind.NegativeLookaround: 3056case RegexNodeKind.Nothing: 3060case RegexNodeKind.Empty: 3064case RegexNodeKind.UpdateBumpalong: 3076Debug.Assert(node.Kind is RegexNodeKind.Atomic or RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround or RegexNodeKind.ExpressionConditional, $"Unexpected type: {node.Kind}"); 3077Debug.Assert(node.Kind is RegexNodeKind.ExpressionConditional ? node.ChildCount() >= 1 : node.ChildCount() == 1, $"Unexpected number of children: {node.ChildCount()}"); 3083if (node.Kind is RegexNodeKind.Atomic && !analysis.MayBacktrack(child)) 3120Debug.Assert(node.Kind is RegexNodeKind.UpdateBumpalong, $"Unexpected type: {node.Kind}"); 3140Debug.Assert(node.Kind is RegexNodeKind.Concatenate, $"Unexpected type: {node.Kind}"); 3198if (next.Kind is not RegexNodeKind.UpdateBumpalong) // skip node types that don't have a semantic impact 3286Debug.Assert(node.Kind is RegexNodeKind.Boundary or RegexNodeKind.NonBoundary or RegexNodeKind.ECMABoundary or RegexNodeKind.NonECMABoundary, $"Unexpected type: {node.Kind}"); 3304case RegexNodeKind.Boundary or RegexNodeKind.NonBoundary: 3318if (node.Kind is RegexNodeKind.Boundary) 3331if (node.Kind is RegexNodeKind.ECMABoundary) 3346Debug.Assert(node.Kind is RegexNodeKind.Beginning or RegexNodeKind.Start or RegexNodeKind.Bol or RegexNodeKind.End or RegexNodeKind.EndZ or RegexNodeKind.Eol, $"Unexpected type: {node.Kind}"); 3353case RegexNodeKind.Beginning: 3354case RegexNodeKind.Start: 3365if (node.Kind == RegexNodeKind.Beginning) 3377case RegexNodeKind.Bol: 3408case RegexNodeKind.End: 3425case RegexNodeKind.EndZ: 3442goto case RegexNodeKind.Eol; 3444case RegexNodeKind.Eol: 3484Debug.Assert(node.Kind is RegexNodeKind.Multi, $"Unexpected type: {node.Kind}"); 3536Debug.Assert(node.Kind is RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop, $"Unexpected type: {node.Kind}"); 3675case RegexNodeKind.One or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy: 3680case RegexNodeKind.Notone or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy: 3685case RegexNodeKind.Multi: 3811Debug.Assert(node.Kind is RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy, $"Unexpected type: {node.Kind}"); 3912node.Kind is RegexNodeKind.Notonelazy && 4053node.Kind is RegexNodeKind.Setlazy && 4158Debug.Assert(node.Kind is RegexNodeKind.Lazyloop, $"Unexpected type: {node.Kind}"); 4669Debug.Assert(node.Kind is RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic, $"Unexpected type: {node.Kind}"); 4916Debug.Assert(node.Kind is RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic, $"Unexpected type: {node.Kind}"); 5005Debug.Assert(node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop, $"Unexpected type: {node.Kind}"); 5043Debug.Assert(node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop, $"Unexpected type: {node.Kind}"); 5441if (node.Kind == RegexNodeKind.Multi) 5474if (node.Kind == RegexNodeKind.Multi) 5667if (root.Kind is RegexNodeKind.Multi or RegexNodeKind.One or RegexNodeKind.Notone or RegexNodeKind.Set) 5685Ldc((root.Kind == RegexNodeKind.Multi ? root.Str!.Length : 1) * (!rtl ? 1 : -1));
System\Text\RegularExpressions\RegexFindOptimizations.cs (23)
56if (rightToLeft && LeadingAnchor == RegexNodeKind.Bol) 59LeadingAnchor = RegexNodeKind.Unknown; 61if (LeadingAnchor is RegexNodeKind.Beginning or RegexNodeKind.Start or RegexNodeKind.EndZ or RegexNodeKind.End) 65(RegexNodeKind.Beginning, false) => FindNextStartingPositionMode.LeadingAnchor_LeftToRight_Beginning, 66(RegexNodeKind.Beginning, true) => FindNextStartingPositionMode.LeadingAnchor_RightToLeft_Beginning, 67(RegexNodeKind.Start, false) => FindNextStartingPositionMode.LeadingAnchor_LeftToRight_Start, 68(RegexNodeKind.Start, true) => FindNextStartingPositionMode.LeadingAnchor_RightToLeft_Start, 69(RegexNodeKind.End, false) => FindNextStartingPositionMode.LeadingAnchor_LeftToRight_End, 70(RegexNodeKind.End, true) => FindNextStartingPositionMode.LeadingAnchor_RightToLeft_End, 83if (TrailingAnchor is RegexNodeKind.End or RegexNodeKind.EndZ && 90FindMode = TrailingAnchor == RegexNodeKind.End ? 280LeadingAnchor == RegexNodeKind.Bol; // there's a leading BOL anchor we can otherwise search for 286public RegexNodeKind LeadingAnchor { get; private set; } 289public RegexNodeKind TrailingAnchor { get; } 409Debug.Assert(LeadingAnchor != RegexNodeKind.Bol, "BOL isn't enabled for RTL"); 535if (LeadingAnchor == RegexNodeKind.Bol) 822Debug.Assert(loopNode.Kind is RegexNodeKind.Setloop or RegexNodeKind.Setlazy or RegexNodeKind.Setloopatomic);
System\Text\RegularExpressions\RegexNode.cs (745)
23public RegexNodeKind Kind { get; private set; } 26/// <remarks>For a <see cref="RegexNodeKind.Multi"/>, this is the string from the expression. For an <see cref="IsSetFamily"/> node, this is the character class string from <see cref="RegexCharClass"/>.</remarks> 51public RegexNode(RegexNodeKind kind, RegexOptions options) 57public RegexNode(RegexNodeKind kind, RegexOptions options, char ch) 64public RegexNode(RegexNodeKind kind, RegexOptions options, string str) 71public RegexNode(RegexNodeKind kind, RegexOptions options, int m) 78public RegexNode(RegexNodeKind kind, RegexOptions options, int m, int n) 89Debug.Assert(Kind is RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or 90RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or 91RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic); 121return new RegexNode(RegexNodeKind.One, options & ~RegexOptions.IgnoreCase, ch); 127return new RegexNode(RegexNodeKind.Set, options & ~RegexOptions.IgnoreCase, stringSet); 131return new RegexNode(RegexNodeKind.One, options, ch); 138Kind == RegexNodeKind.Concatenate && 150private void MakeRep(RegexNodeKind kind, int min, int max) 152Kind += kind - RegexNodeKind.One; 169case RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop: 172Kind += RegexNodeKind.Oneloopatomic - RegexNodeKind.Oneloop; 175case RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy: 179Kind += RegexNodeKind.Oneloopatomic - RegexNodeKind.Onelazy; 189Kind = RegexNodeKind.Empty; 193else if (Kind == RegexNodeKind.Oneloopatomic && N is >= 2 and <= MultiVsRepeaterLimit) 197Kind = RegexNodeKind.Multi; 204case RegexNodeKind.Loop: 205if (Parent is not { Kind: RegexNodeKind.Atomic }) 207RegexNode loopAsChild = new(RegexNodeKind.Loop, Options, M, N); 208Kind = RegexNodeKind.Atomic; 215case RegexNodeKind.Lazyloop: 225goto case RegexNodeKind.Loop; 228Kind = RegexNodeKind.Empty; 243Debug.Assert(Kind == RegexNodeKind.Capture, "Every generated tree should begin with a capture node"); 262Debug.Assert(Kind != RegexNodeKind.Group, "All Group nodes should have been removed."); 267case RegexNodeKind.Group: 271case RegexNodeKind.Beginning: 272case RegexNodeKind.Bol: 273case RegexNodeKind.Boundary: 274case RegexNodeKind.ECMABoundary: 275case RegexNodeKind.Empty: 276case RegexNodeKind.End: 277case RegexNodeKind.EndZ: 278case RegexNodeKind.Eol: 279case RegexNodeKind.Multi: 280case RegexNodeKind.NonBoundary: 281case RegexNodeKind.NonECMABoundary: 282case RegexNodeKind.Nothing: 283case RegexNodeKind.Notone: 284case RegexNodeKind.Notonelazy: 285case RegexNodeKind.Notoneloop: 286case RegexNodeKind.Notoneloopatomic: 287case RegexNodeKind.One: 288case RegexNodeKind.Onelazy: 289case RegexNodeKind.Oneloop: 290case RegexNodeKind.Oneloopatomic: 291case RegexNodeKind.Backreference: 292case RegexNodeKind.Set: 293case RegexNodeKind.Setlazy: 294case RegexNodeKind.Setloop: 295case RegexNodeKind.Setloopatomic: 296case RegexNodeKind.Start: 297case RegexNodeKind.UpdateBumpalong: 301case RegexNodeKind.Atomic: 302case RegexNodeKind.Capture: 303case RegexNodeKind.Lazyloop: 304case RegexNodeKind.Loop: 305case RegexNodeKind.NegativeLookaround: 306case RegexNodeKind.PositiveLookaround: 310case RegexNodeKind.BackreferenceConditional: 314case RegexNodeKind.ExpressionConditional: 318case RegexNodeKind.Concatenate: 319case RegexNodeKind.Alternate: 331case RegexNodeKind.Multi: 336case RegexNodeKind.Set: 337case RegexNodeKind.Setloop: 338case RegexNodeKind.Setloopatomic: 339case RegexNodeKind.Setlazy: 351case RegexNodeKind.Backreference: 372Debug.Assert(rootNode.Kind == RegexNodeKind.Capture); 429case RegexNodeKind.Atomic: 433case RegexNodeKind.Concatenate: 438case RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when node.N == int.MaxValue: 439case RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy when node.N == int.MaxValue && !atomicByAncestry: 440if (node.Parent is { Kind: RegexNodeKind.Concatenate } parent) 442parent.InsertChild(1, new RegexNode(RegexNodeKind.UpdateBumpalong, node.Options)); 523case RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop: 524case RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy: 530case RegexNodeKind.Atomic: 531case RegexNodeKind.PositiveLookaround: 532case RegexNodeKind.NegativeLookaround: 542case RegexNodeKind.Capture: 543case RegexNodeKind.Concatenate when !rtl: 545if ((existingChild.Kind is RegexNodeKind.Alternate or RegexNodeKind.BackreferenceConditional or RegexNodeKind.ExpressionConditional or RegexNodeKind.Loop or RegexNodeKind.Lazyloop) && 546node.Parent is not { Kind: RegexNodeKind.Atomic }) // validate grandparent isn't atomic 548var atomic = new RegexNode(RegexNodeKind.Atomic, existingChild.Options); 558case RegexNodeKind.Alternate: 559case RegexNodeKind.BackreferenceConditional: 560case RegexNodeKind.ExpressionConditional: 568if (node.Kind != RegexNodeKind.ExpressionConditional) // ReduceExpressionConditional will have already applied ending backtracking removal 583case RegexNodeKind.Lazyloop: 584case RegexNodeKind.Loop: 589Debug.Assert(node.Kind is RegexNodeKind.Atomic or RegexNodeKind.Empty or RegexNodeKind.Loop or RegexNodeKind.Lazyloop); 591if (node.Kind is RegexNodeKind.Atomic) 594Debug.Assert(node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop); 597if (node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop) 631case RegexNodeKind.Backreference: 638RegexNodeKind.Alternate => ReduceAlternation(), 639RegexNodeKind.Atomic => ReduceAtomic(), 640RegexNodeKind.Concatenate => ReduceConcatenation(), 641RegexNodeKind.Group => ReduceGroup(), 642RegexNodeKind.Loop or RegexNodeKind.Lazyloop => ReduceLoops(), 643RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround => ReduceLookaround(), 644RegexNodeKind.Set or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy => ReduceSet(), 645RegexNodeKind.ExpressionConditional => ReduceExpressionConditional(), 646RegexNodeKind.BackreferenceConditional => ReduceBackreferenceConditional(), 659Debug.Assert(Kind is RegexNodeKind.Alternate or RegexNodeKind.Concatenate); 6620 => new RegexNode(Kind == RegexNodeKind.Alternate ? RegexNodeKind.Nothing : RegexNodeKind.Empty, Options), 676Debug.Assert(Kind == RegexNodeKind.Group); 679while (u.Kind == RegexNodeKind.Group) 704Debug.Assert(Kind == RegexNodeKind.Atomic); 709while (child.Kind == RegexNodeKind.Atomic) 719case RegexNodeKind.Empty: 720case RegexNodeKind.Nothing: 724case RegexNodeKind.Oneloopatomic: 725case RegexNodeKind.Notoneloopatomic: 726case RegexNodeKind.Setloopatomic: 731case RegexNodeKind.Oneloop: 732case RegexNodeKind.Notoneloop: 733case RegexNodeKind.Setloop: 734case RegexNodeKind.Onelazy: 735case RegexNodeKind.Notonelazy: 736case RegexNodeKind.Setlazy: 742case RegexNodeKind.Alternate: 751if (branches[0].Kind == RegexNodeKind.Empty) 753return new RegexNode(RegexNodeKind.Empty, child.Options); 762if (branches[i].Kind == RegexNodeKind.Empty) 843(child.Child(0).Kind is RegexNodeKind.Empty || child.Child(1).Kind is RegexNodeKind.Empty); // can be transformed into a ? or ?? 858return child.Kind == RegexNodeKind.Empty ? 873Debug.Assert(Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop); 876RegexNodeKind kind = Kind; 889if (kind == RegexNodeKind.Loop) 893case RegexNodeKind.Oneloop: 894case RegexNodeKind.Oneloopatomic: 895case RegexNodeKind.Notoneloop: 896case RegexNodeKind.Notoneloopatomic: 897case RegexNodeKind.Setloop: 898case RegexNodeKind.Setloopatomic: 907case RegexNodeKind.Onelazy: 908case RegexNodeKind.Notonelazy: 909case RegexNodeKind.Setlazy: 943return new RegexNode(RegexNodeKind.Nothing, Options); 954case RegexNodeKind.One: 955case RegexNodeKind.Notone: 956case RegexNodeKind.Set: 957child.MakeRep(u.Kind == RegexNodeKind.Lazyloop ? RegexNodeKind.Onelazy : RegexNodeKind.Oneloop, u.M, u.N); 961case RegexNodeKind.Empty: 966case RegexNodeKind.PositiveLookaround when ContainsKind(child, [RegexNodeKind.Capture]) is false: 967case RegexNodeKind.NegativeLookaround or 968RegexNodeKind.Beginning or RegexNodeKind.Start or 969RegexNodeKind.Bol or RegexNodeKind.Eol or 970RegexNodeKind.End or RegexNodeKind.EndZ or 971RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or 972RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary: 982u = u.M == 0 ? new RegexNode(RegexNodeKind.Empty, Options) : child; 1005Debug.Assert(Kind is RegexNodeKind.Set or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy); 1010Kind = RegexNodeKind.Nothing; 1018Kind == RegexNodeKind.Set ? RegexNodeKind.One : 1019Kind == RegexNodeKind.Setloop ? RegexNodeKind.Oneloop : 1020Kind == RegexNodeKind.Setloopatomic ? RegexNodeKind.Oneloopatomic : 1021RegexNodeKind.Onelazy; 1028Kind == RegexNodeKind.Set ? RegexNodeKind.Notone : 1029Kind == RegexNodeKind.Setloop ? RegexNodeKind.Notoneloop : 1030Kind == RegexNodeKind.Setloopatomic ? RegexNodeKind.Notoneloopatomic : 1031RegexNodeKind.Notonelazy; 1065Debug.Assert(Kind == RegexNodeKind.Alternate); 1070return new RegexNode(RegexNodeKind.Nothing, Options); 1078if (node.Kind == RegexNodeKind.Alternate) 1081if (node.Kind == RegexNodeKind.Alternate) 1084if (node.Kind == RegexNodeKind.Alternate) 1092if (node.Kind is RegexNodeKind.Alternate && node.ChildCount() == 2) 1094if (node.Child(1).Kind is RegexNodeKind.Empty) 1098else if (node.Child(0).Kind is RegexNodeKind.Empty) 1135if (at.Kind == RegexNodeKind.Alternate) 1153else if (at.Kind is RegexNodeKind.Set or RegexNodeKind.One) 1158if (at.Kind == RegexNodeKind.Set) 1182if (prev.Kind == RegexNodeKind.One) 1192if (at.Kind == RegexNodeKind.One) 1202prev.Kind = RegexNodeKind.Set; 1209else if (at.Kind == RegexNodeKind.Nothing) 1233Debug.Assert(alternation.Kind == RegexNodeKind.Alternate); 1252RegexNode required = startingNode.Kind == RegexNodeKind.Concatenate ? startingNode.Child(0) : startingNode; 1255case RegexNodeKind.One or RegexNodeKind.Notone or RegexNodeKind.Set: 1256case RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Setloopatomic: 1257case RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop or RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy when required.M == required.N: 1258case RegexNodeKind.Beginning or RegexNodeKind.Start or RegexNodeKind.Bol 1259or RegexNodeKind.End or RegexNodeKind.EndZ or RegexNodeKind.Eol 1260or RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary 1261or RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary: 1273RegexNode other = endingNode.Kind == RegexNodeKind.Concatenate ? endingNode.Child(0) : endingNode; 1292var newAlternate = new RegexNode(RegexNodeKind.Alternate, alternation.Options); 1295if (children[i].Kind == RegexNodeKind.Concatenate) 1303newAlternate.AddChild(new RegexNode(RegexNodeKind.Empty, children[i].Options)); 1308if (alternation.Parent is RegexNode { Kind: RegexNodeKind.Atomic }) 1310var atomic = new RegexNode(RegexNodeKind.Atomic, alternation.Options); 1317var newConcat = new RegexNode(RegexNodeKind.Concatenate, alternation.Options); 1333Debug.Assert(node.Kind == RegexNodeKind.Alternate); 1344case RegexNodeKind.Empty when !seenEmpty: 1348case RegexNodeKind.Empty: 1349case RegexNodeKind.Nothing: 1376Debug.Assert(alternation.Kind == RegexNodeKind.Alternate); 1403if (startingNode.Kind == RegexNodeKind.One) 1423if (startingNode.Kind == RegexNodeKind.One) 1437Debug.Assert(startingNode.Kind == RegexNodeKind.Multi); 1468new RegexNode(RegexNodeKind.One, startingNodeOptions, startingSpan[0]) : 1469new RegexNode(RegexNodeKind.Multi, startingNodeOptions, startingSpan.ToString()); 1470var newAlternate = new RegexNode(RegexNodeKind.Alternate, startingNodeOptions); 1474ProcessOneOrMulti(branch.Kind == RegexNodeKind.Concatenate ? branch.Child(0) : branch, startingSpan); 1482if (node.Kind == RegexNodeKind.One) 1486node.Kind = RegexNodeKind.Empty; 1491Debug.Assert(node.Kind == RegexNodeKind.Multi); 1495node.Kind = RegexNodeKind.Empty; 1500node.Kind = RegexNodeKind.One; 1512if (alternation.Parent is RegexNode parent && parent.Kind == RegexNodeKind.Atomic) 1514var atomic = new RegexNode(RegexNodeKind.Atomic, startingNodeOptions); 1519var newConcat = new RegexNode(RegexNodeKind.Concatenate, startingNodeOptions); 1539RegexNode branch = Kind == RegexNodeKind.Concatenate ? Child(0) : this; 1540return branch.Kind is RegexNodeKind.One or RegexNodeKind.Multi ? branch : null; 1546Debug.Assert(Kind is RegexNodeKind.One or RegexNodeKind.Multi || (IsOneFamily && M > 0)); 1561Debug.Assert(Kind is RegexNodeKind.Alternate); 1585if (startingLiteralNode.IsOneFamily || startingLiteralNode.Kind is RegexNodeKind.Multi) 1631case RegexNodeKind.One: 1632case RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy when node.M > 0: 1633case RegexNodeKind.Notone: 1634case RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy when node.M > 0: 1635case RegexNodeKind.Set: 1636case RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy when node.M > 0: 1637case RegexNodeKind.Multi: 1640case RegexNodeKind.Atomic: 1641case RegexNodeKind.Concatenate: 1642case RegexNodeKind.Capture: 1643case RegexNodeKind.Group: 1644case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.M > 0: 1645case RegexNodeKind.PositiveLookaround when allowZeroWidth: 1666case RegexNodeKind.One or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy: 1669case RegexNodeKind.Notone or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy: 1672case RegexNodeKind.Set or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy: 1688case RegexNodeKind.Multi: 1731Debug.Assert(Kind == RegexNodeKind.Concatenate); 1737return new RegexNode(RegexNodeKind.Empty, Options); 1747if (child.Kind == RegexNodeKind.Nothing) 1773Debug.Assert(Kind == RegexNodeKind.Concatenate); 1790if (at.Kind == RegexNodeKind.Concatenate && 1809else if (at.Kind is RegexNodeKind.Multi or RegexNodeKind.One) 1823if (prev.Kind == RegexNodeKind.One) 1825prev.Kind = RegexNodeKind.Multi; 1830((at.Kind == RegexNodeKind.One) ? $"{prev.Str}{at.Ch}" : prev.Str + at.Str) : 1831((at.Kind == RegexNodeKind.One) ? $"{at.Ch}{prev.Str}" : at.Str + prev.Str); 1833else if (at.Kind == RegexNodeKind.Empty) 1856Debug.Assert(Kind == RegexNodeKind.Concatenate); 1894case RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy when nextNode.Kind == currentNode.Kind && currentNode.Ch == nextNode.Ch: 1895case RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy when nextNode.Kind == currentNode.Kind && currentNode.Str == nextNode.Str: 1897currentNode.Kind is RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Setloopatomic) 1920case RegexNodeKind.Oneloop or RegexNodeKind.Onelazy when nextNode.Kind == RegexNodeKind.One && currentNode.Ch == nextNode.Ch: 1921case RegexNodeKind.Notoneloop or RegexNodeKind.Notonelazy when nextNode.Kind == RegexNodeKind.Notone && currentNode.Ch == nextNode.Ch: 1922case RegexNodeKind.Setloop or RegexNodeKind.Setlazy when nextNode.Kind == RegexNodeKind.Set && currentNode.Str == nextNode.Str: 1936case RegexNodeKind.Oneloop or RegexNodeKind.Onelazy when 1937nextNode.Kind == RegexNodeKind.Multi && 1970nextNode.Kind = RegexNodeKind.One; 1988case RegexNodeKind.One when (nextNode.Kind is RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy) && currentNode.Ch == nextNode.Ch: 1989case RegexNodeKind.Notone when (nextNode.Kind is RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy) && currentNode.Ch == nextNode.Ch: 1990case RegexNodeKind.Set when (nextNode.Kind is RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy) && currentNode.Str == nextNode.Str: 2003case RegexNodeKind.Notone when nextNode.Kind == currentNode.Kind && currentNode.Ch == nextNode.Ch: 2004case RegexNodeKind.Set when nextNode.Kind == RegexNodeKind.Set && currentNode.Str == nextNode.Str: 2005currentNode.MakeRep(RegexNodeKind.Oneloop, 2, 2); 2010case RegexNodeKind.Beginning or RegexNodeKind.Start or 2011RegexNodeKind.End or RegexNodeKind.EndZ or 2012RegexNodeKind.Bol or RegexNodeKind.Eol or 2013RegexNodeKind.Boundary or RegexNodeKind.NonBoundary or 2014RegexNodeKind.ECMABoundary or RegexNodeKind.NonECMABoundary 2058if (Kind is not RegexNodeKind.Concatenate) 2082while (node.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) 2090case RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: true, allowLazy: false): 2099case RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy or RegexNodeKind.Setlazy when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: false, allowLazy: true): 2115node.Kind -= RegexNodeKind.Onelazy - RegexNodeKind.Oneloop; // lazy to greedy 2119case RegexNodeKind.Loop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: true, allowLazy: false): 2120case RegexNodeKind.Lazyloop when CanBeMadeAtomic(node, subsequent, iterateNullableSubsequent: false, allowLazy: true): 2134while (loopChild.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) 2146RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or 2147RegexNodeKind.Multi or 2148RegexNodeKind.One or RegexNodeKind.Notone or RegexNodeKind.Set && 2153else if (node.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop) 2157goto case RegexNodeKind.Loop; 2165case RegexNodeKind.Loop: 2175case RegexNodeKind.Lazyloop: 2185case RegexNodeKind.Alternate or RegexNodeKind.BackreferenceConditional or RegexNodeKind.ExpressionConditional: 2196for (int b = node.Kind == RegexNodeKind.ExpressionConditional ? 1 : 0; b < alternateBranches; b++) 2210Debug.Assert(Kind is RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround); 2218if (Kind is RegexNodeKind.NegativeLookaround && ContainsKind(Child(0), [RegexNodeKind.Backreference, RegexNodeKind.BackreferenceConditional]) is false) 2233if (node is { Kind: RegexNodeKind.Capture, N: -1 }) 2264if (Kind is RegexNodeKind.PositiveLookaround) 2267child.Kind is RegexNodeKind.Empty) 2272else if (Kind is RegexNodeKind.NegativeLookaround) 2277if (child.Kind is RegexNodeKind.Empty) 2279Kind = RegexNodeKind.Nothing; 2287private static bool IsZeroWidthAssertion(RegexNodeKind kind) => kind is 2288RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround or 2289RegexNodeKind.Beginning or RegexNodeKind.Start or 2290RegexNodeKind.Bol or RegexNodeKind.Eol or 2291RegexNodeKind.End or RegexNodeKind.EndZ or 2292RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or 2293RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary or 2294RegexNodeKind.UpdateBumpalong; 2298private static bool? ContainsKind(RegexNode node, ReadOnlySpan<RegexNodeKind> kinds) 2300foreach (RegexNodeKind kind in kinds) 2330Debug.Assert(Kind == RegexNodeKind.BackreferenceConditional); 2339AddChild(new RegexNode(RegexNodeKind.Empty, Options)); 2348Debug.Assert(Kind == RegexNodeKind.ExpressionConditional); 2357AddChild(new RegexNode(RegexNodeKind.Empty, Options)); 2366if (condition.Kind == RegexNodeKind.PositiveLookaround && (condition.Options & RegexOptions.RightToLeft) == 0) 2391Debug.Assert(loopNode.Kind is RegexNodeKind.Oneloop or RegexNodeKind.Notoneloop or RegexNodeKind.Setloop); 2402case RegexNodeKind.One when CharInLoopSet(loopNode, literal.Ch): // e.g. \w+a\s : 'a' is in \w, check \s is disjoint 2403case RegexNodeKind.Set when loopNode.Kind is RegexNodeKind.Setloop && RegexCharClass.IsSubsetOf(literal.Str!, loopNode.Str!): // e.g. \d+[0-9]\s 2411case RegexNodeKind.Multi when CharInLoopSet(loopNode, literal.Str![0]) && !CharInLoopSet(loopNode, literal.Str[1]): 2423RegexNodeKind.Oneloop => loopNode.Ch == ch, 2424RegexNodeKind.Notoneloop => loopNode.Ch != ch, 2425RegexNodeKind.Setloop => RegexCharClass.CharInClass(ch, loopNode.Str!), 2447while (node.Kind is RegexNodeKind.Capture or RegexNodeKind.Concatenate) 2465case RegexNodeKind.Concatenate: 2466case RegexNodeKind.Capture: 2467case RegexNodeKind.Atomic: 2471case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when subsequent.M > 0: 2479case RegexNodeKind.PositiveLookaround when (subsequent.Options & RegexOptions.RightToLeft) == 0: 2503case RegexNodeKind.Alternate: 2504case RegexNodeKind.ExpressionConditional when childCount is 3: // condition, yes, and no branch 2519case RegexNodeKind.Oneloop: 2520case RegexNodeKind.Onelazy when allowLazy: 2523case RegexNodeKind.One when node.Ch != subsequent.Ch: 2524case RegexNodeKind.Notone when node.Ch == subsequent.Ch: 2525case RegexNodeKind.Set when !RegexCharClass.CharInClass(node.Ch, subsequent.Str!): 2526case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M > 0 && node.Ch != subsequent.Ch: 2527case RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic when subsequent.M > 0 && node.Ch == subsequent.Ch: 2528case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M > 0 && !RegexCharClass.CharInClass(node.Ch, subsequent.Str!): 2529case RegexNodeKind.Multi when node.Ch != subsequent.Str![0]: 2530case RegexNodeKind.End: 2531case RegexNodeKind.EndZ or RegexNodeKind.Eol when node.Ch != '\n': 2532case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsBoundaryWordChar(node.Ch): 2533case RegexNodeKind.NonBoundary when node.M > 0 && !RegexCharClass.IsBoundaryWordChar(node.Ch): 2534case RegexNodeKind.ECMABoundary when node.M > 0 && RegexCharClass.IsECMAWordChar(node.Ch): 2535case RegexNodeKind.NonECMABoundary when node.M > 0 && !RegexCharClass.IsECMAWordChar(node.Ch): 2538case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && node.Ch != subsequent.Ch: 2539case RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic when subsequent.M == 0 && node.Ch == subsequent.Ch: 2540case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M == 0 && !RegexCharClass.CharInClass(node.Ch, subsequent.Str!): 2549case RegexNodeKind.Notoneloop: 2550case RegexNodeKind.Notonelazy when allowLazy: 2553case RegexNodeKind.One when node.Ch == subsequent.Ch: 2554case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M > 0 && node.Ch == subsequent.Ch: 2555case RegexNodeKind.Multi when node.Ch == subsequent.Str![0]: 2556case RegexNodeKind.End: 2559case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && node.Ch == subsequent.Ch: 2568case RegexNodeKind.Setloop: 2569case RegexNodeKind.Setlazy when allowLazy: 2572case RegexNodeKind.One when !RegexCharClass.CharInClass(subsequent.Ch, node.Str!): 2573case RegexNodeKind.Set when !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!): 2574case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M > 0 && !RegexCharClass.CharInClass(subsequent.Ch, node.Str!): 2575case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M > 0 && !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!): 2576case RegexNodeKind.Multi when !RegexCharClass.CharInClass(subsequent.Str![0], node.Str!): 2577case RegexNodeKind.End: 2578case RegexNodeKind.EndZ or RegexNodeKind.Eol when !RegexCharClass.CharInClass('\n', node.Str!): 2579case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsSubsetOf(node.Str!, RegexCharClass.WordClass): 2580case RegexNodeKind.NonBoundary when node.M > 0 && node.Str is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass: 2581case RegexNodeKind.ECMABoundary when node.M > 0 && node.Str is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass: 2582case RegexNodeKind.NonECMABoundary when node.M > 0 && node.Str is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass: 2585case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && !RegexCharClass.CharInClass(subsequent.Ch, node.Str!): 2586case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M == 0 && !RegexCharClass.MayOverlap(node.Str!, subsequent.Str!): 2595case RegexNodeKind.Loop: 2596case RegexNodeKind.Lazyloop when allowLazy: 2619case RegexNodeKind.One when !CharInStartingOrEndingSet(subsequent.Ch): 2620case RegexNodeKind.Set when !MayOverlapStartingOrEndingSet(subsequent.Str!): 2621case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M > 0 && !CharInStartingOrEndingSet(subsequent.Ch): 2622case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M > 0 && !MayOverlapStartingOrEndingSet(subsequent.Str!): 2623case RegexNodeKind.Multi when !CharInStartingOrEndingSet(subsequent.Str![0]): 2624case RegexNodeKind.End: 2625case RegexNodeKind.EndZ or RegexNodeKind.Eol when !CharInStartingOrEndingSet('\n'): 2626case RegexNodeKind.Boundary when node.M > 0 && RegexCharClass.IsSubsetOf(loopStartingSet, RegexCharClass.WordClass) && RegexCharClass.IsSubsetOf(loopEndingSet, RegexCharClass.WordClass): 2627case RegexNodeKind.NonBoundary when node.M > 0 && (loopStartingSet is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass) && (loopEndingSet is RegexCharClass.NotWordClass or RegexCharClass.NotDigitClass): 2628case RegexNodeKind.ECMABoundary when node.M > 0 && (loopStartingSet is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass) && (loopEndingSet is RegexCharClass.ECMAWordClass or RegexCharClass.ECMADigitClass): 2629case RegexNodeKind.NonECMABoundary when node.M > 0 && (loopStartingSet is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass) && (loopEndingSet is RegexCharClass.NotECMAWordClass or RegexCharClass.NotDigitClass): 2632case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when subsequent.M == 0 && !CharInStartingOrEndingSet(subsequent.Ch): 2633case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when subsequent.M == 0 && !MayOverlapStartingOrEndingSet(subsequent.Str!): 2688case RegexNodeKind.Atomic: 2689case RegexNodeKind.Alternate: 2690case RegexNodeKind.Capture: 2694case RegexNodeKind.Concatenate: 2725RegexNodeKind.Alternate => true, 2726RegexNodeKind.Loop or RegexNodeKind.Lazyloop when M != N => true, 2727RegexNodeKind.Oneloop or RegexNodeKind.Onelazy or 2728RegexNodeKind.Notoneloop or RegexNodeKind.Notonelazy or 2729RegexNodeKind.Setloop or RegexNodeKind.Setlazy when M != N => true, 2773Debug.Assert(node.Kind is not RegexNodeKind.Concatenate, "The existing logic assumes that the node itself isn't a concatenation."); 2786case RegexNodeKind.Atomic: 2787case RegexNodeKind.Alternate: 2788case RegexNodeKind.Capture: 2792case RegexNodeKind.Concatenate: 2828case RegexNodeKind.One: 2829case RegexNodeKind.Notone: 2830case RegexNodeKind.Set: 2834case RegexNodeKind.Multi: 2838case RegexNodeKind.Notonelazy: 2839case RegexNodeKind.Notoneloop: 2840case RegexNodeKind.Notoneloopatomic: 2841case RegexNodeKind.Onelazy: 2842case RegexNodeKind.Oneloop: 2843case RegexNodeKind.Oneloopatomic: 2844case RegexNodeKind.Setlazy: 2845case RegexNodeKind.Setloop: 2846case RegexNodeKind.Setloopatomic: 2850case RegexNodeKind.Lazyloop: 2851case RegexNodeKind.Loop: 2855case RegexNodeKind.Alternate: 2868case RegexNodeKind.BackreferenceConditional: 2872case RegexNodeKind.ExpressionConditional: 2876case RegexNodeKind.Concatenate: 2888case RegexNodeKind.Atomic: 2889case RegexNodeKind.Capture: 2890case RegexNodeKind.Group: 2895case RegexNodeKind.Empty: 2896case RegexNodeKind.Nothing: 2897case RegexNodeKind.UpdateBumpalong: 2901case RegexNodeKind.Beginning: 2902case RegexNodeKind.Bol: 2903case RegexNodeKind.Boundary: 2904case RegexNodeKind.ECMABoundary: 2905case RegexNodeKind.End: 2906case RegexNodeKind.EndZ: 2907case RegexNodeKind.Eol: 2908case RegexNodeKind.NonBoundary: 2909case RegexNodeKind.NonECMABoundary: 2910case RegexNodeKind.Start: 2911case RegexNodeKind.NegativeLookaround: 2912case RegexNodeKind.PositiveLookaround: 2914case RegexNodeKind.Backreference: 2922goto case RegexNodeKind.Empty; 2941case RegexNodeKind.One: 2942case RegexNodeKind.Notone: 2943case RegexNodeKind.Set: 2947case RegexNodeKind.Multi: 2951case RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or 2952RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or 2953RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic: 2957case RegexNodeKind.Loop or RegexNodeKind.Lazyloop: 2972case RegexNodeKind.Alternate: 2995case RegexNodeKind.BackreferenceConditional: 2996case RegexNodeKind.ExpressionConditional: 2999int i = Kind == RegexNodeKind.BackreferenceConditional ? 0 : 1; 3005case RegexNodeKind.Concatenate: 3027case RegexNodeKind.Atomic: 3028case RegexNodeKind.Capture: 3033case RegexNodeKind.Empty: 3034case RegexNodeKind.Nothing: 3035case RegexNodeKind.UpdateBumpalong: 3036case RegexNodeKind.Beginning: 3037case RegexNodeKind.Bol: 3038case RegexNodeKind.Boundary: 3039case RegexNodeKind.ECMABoundary: 3040case RegexNodeKind.End: 3041case RegexNodeKind.EndZ: 3042case RegexNodeKind.Eol: 3043case RegexNodeKind.NonBoundary: 3044case RegexNodeKind.NonECMABoundary: 3045case RegexNodeKind.Start: 3046case RegexNodeKind.PositiveLookaround: 3047case RegexNodeKind.NegativeLookaround: 3051case RegexNodeKind.Backreference: 3059goto case RegexNodeKind.Empty; 3090Debug.Assert(Kind == RegexNodeKind.Concatenate, $"Expected Concatenate, got {Kind}"); 3112while (child.Kind is RegexNodeKind.Capture or RegexNodeKind.Atomic) 3118if (child.Kind is RegexNodeKind.One) 3131else if (child.Kind is RegexNodeKind.Multi) 3143else if (child.Kind is RegexNodeKind.Set || 3144(child.Kind is RegexNodeKind.Setloop or RegexNodeKind.Setlazy or RegexNodeKind.Setloopatomic && child.M == child.N)) 3153vsb.Append((char)(twoChars[0] | 0x20), child.Kind is RegexNodeKind.Set ? 1 : child.M); 3155else if (child.Kind is RegexNodeKind.Concatenate) 3175else if (child.Kind is RegexNodeKind.Empty) 3226Debug.Assert(Kind == RegexNodeKind.Concatenate, $"Expected Concatenate, got {Kind}"); 3230RegexNodeKind.One or RegexNodeKind.Notone or RegexNodeKind.Set => true, 3231RegexNodeKind.Multi => true, 3232RegexNodeKind.Oneloop or RegexNodeKind.Onelazy or RegexNodeKind.Oneloopatomic or 3233RegexNodeKind.Notoneloop or RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloopatomic or 3234RegexNodeKind.Setloop or RegexNodeKind.Setlazy or RegexNodeKind.Setloopatomic 3276return new RegexNode(RegexNodeKind.Empty, Options); 3282case <= MultiVsRepeaterLimit when Kind == RegexNodeKind.One: 3288Kind = RegexNodeKind.Multi; 3297case RegexNodeKind.One: 3298case RegexNodeKind.Notone: 3299case RegexNodeKind.Set: 3300MakeRep(lazy ? RegexNodeKind.Onelazy : RegexNodeKind.Oneloop, min, max); 3304var result = new RegexNode(lazy ? RegexNodeKind.Lazyloop : RegexNodeKind.Loop, Options, min, max); 3435public bool IsSetFamily => Kind is RegexNodeKind.Set or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy; 3438public bool IsOneFamily => Kind is RegexNodeKind.One or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy; 3441public bool IsNotoneFamily => Kind is RegexNodeKind.Notone or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy; 3492case RegexNodeKind.Oneloop: 3493case RegexNodeKind.Oneloopatomic: 3494case RegexNodeKind.Notoneloop: 3495case RegexNodeKind.Notoneloopatomic: 3496case RegexNodeKind.Onelazy: 3497case RegexNodeKind.Notonelazy: 3498case RegexNodeKind.One: 3499case RegexNodeKind.Notone: 3502case RegexNodeKind.Capture: 3509case RegexNodeKind.Backreference: 3510case RegexNodeKind.BackreferenceConditional: 3513case RegexNodeKind.Multi: 3521case RegexNodeKind.Set: 3522case RegexNodeKind.Setloop: 3523case RegexNodeKind.Setloopatomic: 3524case RegexNodeKind.Setlazy: 3531case RegexNodeKind.Oneloop: 3532case RegexNodeKind.Oneloopatomic: 3533case RegexNodeKind.Notoneloop: 3534case RegexNodeKind.Notoneloopatomic: 3535case RegexNodeKind.Onelazy: 3536case RegexNodeKind.Notonelazy: 3537case RegexNodeKind.Setloop: 3538case RegexNodeKind.Setloopatomic: 3539case RegexNodeKind.Setlazy: 3540case RegexNodeKind.Loop: 3541case RegexNodeKind.Lazyloop:
System\Text\RegularExpressions\RegexParser.cs (87)
277StartGroup(new RegexNode(RegexNodeKind.Capture, (_options & ~RegexOptions.IgnoreCase), 0, -1)); 347_unit = new RegexNode(RegexNodeKind.Set, _options & ~RegexOptions.IgnoreCase, setString); 400_unit = new RegexNode((_options & RegexOptions.Multiline) != 0 ? RegexNodeKind.Bol : RegexNodeKind.Beginning, _options); 411_unit = new RegexNode((_options & RegexOptions.Multiline) != 0 ? RegexNodeKind.Eol : RegexNodeKind.EndZ, _options); 418_unit = new RegexNode(RegexNodeKind.Set, _options & ~RegexOptions.IgnoreCase, RegexCharClass.AnyClass); 422_unit = new RegexNode(RegexNodeKind.Set, _options & ~RegexOptions.IgnoreCase, RegexCharClass.NotAnyNewLineClass); 426_unit = new RegexNode(RegexNodeKind.Notone, _options & ~RegexOptions.IgnoreCase, '\n'); 544_concatenation = new RegexNode(RegexNodeKind.Concatenate, _options); 829return new RegexNode(RegexNodeKind.Group, _options); 833return new RegexNode(RegexNodeKind.Capture, _options, _autocap++, -1); 846RegexNodeKind nodeType; 853nodeType = RegexNodeKind.Group; 859nodeType = RegexNodeKind.PositiveLookaround; 865nodeType = RegexNodeKind.NegativeLookaround; 870nodeType = RegexNodeKind.Atomic; 893nodeType = RegexNodeKind.PositiveLookaround; 904nodeType = RegexNodeKind.NegativeLookaround; 1007return new RegexNode(RegexNodeKind.Capture, _options, capnum, uncapnum); 1029return new RegexNode(RegexNodeKind.BackreferenceConditional, _options, capnum); 1043return new RegexNode(RegexNodeKind.BackreferenceConditional, _options, tmpCapnum); 1048nodeType = RegexNodeKind.ExpressionConditional; 1072nodeType = RegexNodeKind.Group; 1075if (_group!.Kind != RegexNodeKind.ExpressionConditional || _group.ChildCount() > 0) 1166(_options & RegexOptions.AnyNewLine) != 0 ? AnyNewLineEndZNode() : new RegexNode(RegexNodeKind.EndZ, _options); 1171new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMAWordClass : RegexCharClass.WordClass); 1176new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMAWordClass : RegexCharClass.NotWordClass); 1181new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMASpaceClass : RegexCharClass.SpaceClass); 1186new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMASpaceClass : RegexCharClass.NotSpaceClass); 1191new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.ECMADigitClass : RegexCharClass.DigitClass); 1196new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), (_options & RegexOptions.ECMAScript) != 0 ? RegexCharClass.NotECMADigitClass : RegexCharClass.NotDigitClass); 1213return new RegexNode(RegexNodeKind.Set, (_options & ~RegexOptions.IgnoreCase), cc.ToStringClass()); 1217if (result != null && result.Kind == RegexNodeKind.Backreference && (result.Options & RegexOptions.IgnoreCase) != 0) 1278IsCaptureSlot(capnum) ? new RegexNode(RegexNodeKind.Backreference, _options, capnum) : 1310return scanOnly ? null : new RegexNode(RegexNodeKind.Backreference, _options, capnum); 1324return new RegexNode(RegexNodeKind.Backreference, _options, capnum); 1344_capnames?[capname] is int tmpCapnum ? new RegexNode(RegexNodeKind.Backreference, _options, tmpCapnum) : 1420return new RegexNode(RegexNodeKind.Backreference, _options, capnum); 1430return new RegexNode(RegexNodeKind.Backreference, _options, capnum); 1442return new RegexNode(RegexNodeKind.Backreference, _options, tmpCapnum); 1480return new RegexNode(RegexNodeKind.Backreference, _options, capnum); 1741var lookbehindCr = new RegexNode(RegexNodeKind.PositiveLookaround, lookbehindOpts); 1742lookbehindCr.AddChild(new RegexNode(RegexNodeKind.One, lookbehindOptsNoCase, '\r')); 1745var crThenLf = new RegexNode(RegexNodeKind.Concatenate, lookaheadOpts); 1747crThenLf.AddChild(new RegexNode(RegexNodeKind.One, lookaheadOptsNoCase, '\n')); 1750var guard = new RegexNode(RegexNodeKind.NegativeLookaround, lookaheadOpts); 1769var crlfEnd = new RegexNode(RegexNodeKind.Concatenate, lookaheadOpts); 1770crlfEnd.AddChild(new RegexNode(RegexNodeKind.One, lookaheadOptsNoCase, '\r')); 1771crlfEnd.AddChild(new RegexNode(RegexNodeKind.One, lookaheadOptsNoCase, '\n')); 1772crlfEnd.AddChild(new RegexNode(RegexNodeKind.End, lookaheadOpts)); 1775var anyNewLineOptEnd = new RegexNode(RegexNodeKind.Concatenate, lookaheadOpts); 1776anyNewLineOptEnd.AddChild(new RegexNode(RegexNodeKind.Set, lookaheadOptsNoCase, RegexCharClass.AnyNewLineClass).MakeQuantifier(false, 0, 1)); 1777anyNewLineOptEnd.AddChild(new RegexNode(RegexNodeKind.End, lookaheadOpts)); 1780var innerAlt = new RegexNode(RegexNodeKind.Alternate, lookaheadOpts); 1783var lookahead = new RegexNode(RegexNodeKind.PositiveLookaround, lookaheadOpts); 1787var result = new RegexNode(RegexNodeKind.Concatenate, opts); 1806var innerAlt = new RegexNode(RegexNodeKind.Alternate, lookaheadOpts); 1807innerAlt.AddChild(new RegexNode(RegexNodeKind.Set, lookaheadOptsNoCase, RegexCharClass.AnyNewLineClass)); 1808innerAlt.AddChild(new RegexNode(RegexNodeKind.End, lookaheadOpts)); 1809var lookahead = new RegexNode(RegexNodeKind.PositiveLookaround, lookaheadOpts); 1813var result = new RegexNode(RegexNodeKind.Concatenate, opts); 1832var innerAlt = new RegexNode(RegexNodeKind.Alternate, lookbehindOpts); 1833innerAlt.AddChild(new RegexNode(RegexNodeKind.Set, lookbehindOptsNoCase, RegexCharClass.AnyNewLineClass)); 1834innerAlt.AddChild(new RegexNode(RegexNodeKind.Beginning, lookbehindOpts)); 1835var lookbehind = new RegexNode(RegexNodeKind.PositiveLookaround, lookbehindOpts); 1839var result = new RegexNode(RegexNodeKind.Concatenate, opts); 1847private readonly RegexNodeKind TypeFromCode(char ch) => 1850'b' => (_options & RegexOptions.ECMAScript) != 0 ? RegexNodeKind.ECMABoundary : RegexNodeKind.Boundary, 1851'B' => (_options & RegexOptions.ECMAScript) != 0 ? RegexNodeKind.NonECMABoundary : RegexNodeKind.NonBoundary, 1852'A' => RegexNodeKind.Beginning, 1853'G' => RegexNodeKind.Start, 1854'Z' => RegexNodeKind.EndZ, 1855'z' => RegexNodeKind.End, 1856_ => RegexNodeKind.Nothing, 2198_concatenation!.AddChild(new RegexNode(RegexNodeKind.Multi, _options & ~RegexOptions.IgnoreCase, _pattern.Substring(pos, cch))); 2228if (_group.Kind == RegexNodeKind.ExpressionConditional && _group.ChildCount() == 0) 2244_alternation = new RegexNode(RegexNodeKind.Alternate, _options); 2245_concatenation = new RegexNode(RegexNodeKind.Concatenate, _options); 2253if (_group!.Kind is RegexNodeKind.ExpressionConditional or RegexNodeKind.BackreferenceConditional) 2262_concatenation = new RegexNode(RegexNodeKind.Concatenate, _options); 2268if (_group!.Kind is RegexNodeKind.ExpressionConditional or RegexNodeKind.BackreferenceConditional) 2272if (_group.Kind == RegexNodeKind.BackreferenceConditional && _group.ChildCount() > 2 || _group.ChildCount() > 3)
System\Text\RegularExpressions\RegexPrefixAnalyzer.cs (224)
84case RegexNodeKind.Atomic: 85case RegexNodeKind.Capture: 90case RegexNodeKind.Bol: 91case RegexNodeKind.Eol: 92case RegexNodeKind.Boundary: 93case RegexNodeKind.ECMABoundary: 94case RegexNodeKind.NonBoundary: 95case RegexNodeKind.NonECMABoundary: 96case RegexNodeKind.Beginning: 97case RegexNodeKind.Start: 98case RegexNodeKind.EndZ: 99case RegexNodeKind.End: 100case RegexNodeKind.Empty: 101case RegexNodeKind.UpdateBumpalong: 102case RegexNodeKind.PositiveLookaround: 103case RegexNodeKind.NegativeLookaround: 112case RegexNodeKind.One or RegexNodeKind.Oneloop or RegexNodeKind.Onelazy or RegexNodeKind.Oneloopatomic when !ignoreCase || !RegexCharClass.ParticipatesInCaseConversion(node.Ch): 114int reps = node.Kind is RegexNodeKind.One ? 1 : Math.Min(node.M, MaxPrefixLength); 119return node.Kind is RegexNodeKind.One || reps == node.N; 124case RegexNodeKind.Multi: 156case RegexNodeKind.Set or RegexNodeKind.Setloop or RegexNodeKind.Setlazy or RegexNodeKind.Setloopatomic when !RegexCharClass.IsNegated(node.Str!): // negated sets are too complex to analyze 164int reps = node.Kind is RegexNodeKind.Set ? 1 : Math.Min(node.M, MaxPrefixLength); 209return node.Kind is RegexNodeKind.Set || reps == node.N; 212case RegexNodeKind.Concatenate: 226case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.M > 0: 242case RegexNodeKind.Alternate: 363case RegexNodeKind.Concatenate: 377case RegexNodeKind.Alternate when !rtl: // for RTL we'd need to be matching the suffixes of the alternation cases 422case RegexNodeKind.One: 427case RegexNodeKind.Multi: 432case RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy when node.M > 0: 439case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.M > 0: 454case RegexNodeKind.Atomic: 455case RegexNodeKind.Capture: 459case RegexNodeKind.Bol: 460case RegexNodeKind.Eol: 461case RegexNodeKind.Boundary: 462case RegexNodeKind.ECMABoundary: 463case RegexNodeKind.NonBoundary: 464case RegexNodeKind.NonECMABoundary: 465case RegexNodeKind.Beginning: 466case RegexNodeKind.Start: 467case RegexNodeKind.EndZ: 468case RegexNodeKind.End: 469case RegexNodeKind.Empty: 470case RegexNodeKind.UpdateBumpalong: 471case RegexNodeKind.PositiveLookaround: 472case RegexNodeKind.NegativeLookaround: 491case RegexNodeKind.Atomic: 492case RegexNodeKind.Capture: 493case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.M > 0: 497case RegexNodeKind.Concatenate: 600case RegexNodeKind.One: 609case RegexNodeKind.Onelazy or RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic when node.M > 0: 621case RegexNodeKind.Multi: 633case RegexNodeKind.Set: 641case RegexNodeKind.Setlazy or RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic when node.M > 0: 652case RegexNodeKind.Notone: 658case RegexNodeKind.Notonelazy or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic when node.M == node.N: 662case RegexNodeKind.Beginning: 663case RegexNodeKind.Bol: 664case RegexNodeKind.Boundary: 665case RegexNodeKind.ECMABoundary: 666case RegexNodeKind.Empty: 667case RegexNodeKind.End: 668case RegexNodeKind.EndZ: 669case RegexNodeKind.Eol: 670case RegexNodeKind.NonBoundary: 671case RegexNodeKind.NonECMABoundary: 672case RegexNodeKind.UpdateBumpalong: 673case RegexNodeKind.Start: 674case RegexNodeKind.NegativeLookaround: 675case RegexNodeKind.PositiveLookaround: 681case RegexNodeKind.Atomic: 682case RegexNodeKind.Group: 683case RegexNodeKind.Capture: 686case RegexNodeKind.Lazyloop or RegexNodeKind.Loop when node.M > 0: 696case RegexNodeKind.Concatenate: 709case RegexNodeKind.Alternate when thorough: 954case RegexNodeKind.One or RegexNodeKind.Oneloop or RegexNodeKind.Onelazy or RegexNodeKind.Oneloopatomic: 959return node.Kind is RegexNodeKind.One || node.M > 0 ? true : null; 963case RegexNodeKind.Notone or RegexNodeKind.Notoneloop or RegexNodeKind.Notoneloopatomic or RegexNodeKind.Notonelazy: 977return node.Kind is RegexNodeKind.Notone || node.M > 0 ? true : null; 981case RegexNodeKind.Set or RegexNodeKind.Setloop or RegexNodeKind.Setlazy or RegexNodeKind.Setloopatomic: 996node.Kind is RegexNodeKind.Set || node.M > 0 ? true : 1000case RegexNodeKind.Multi: 1012case RegexNodeKind.Empty: 1013case RegexNodeKind.Nothing: 1014case RegexNodeKind.Bol: 1015case RegexNodeKind.Eol: 1016case RegexNodeKind.Boundary: 1017case RegexNodeKind.NonBoundary: 1018case RegexNodeKind.ECMABoundary: 1019case RegexNodeKind.NonECMABoundary: 1020case RegexNodeKind.Beginning: 1021case RegexNodeKind.Start: 1022case RegexNodeKind.EndZ: 1023case RegexNodeKind.End: 1024case RegexNodeKind.UpdateBumpalong: 1025case RegexNodeKind.PositiveLookaround: 1026case RegexNodeKind.NegativeLookaround: 1030case RegexNodeKind.Atomic: 1031case RegexNodeKind.Capture: 1037case RegexNodeKind.Loop: 1038case RegexNodeKind.Lazyloop: 1050case RegexNodeKind.Concatenate: 1081case RegexNodeKind.Alternate: 1102case RegexNodeKind.BackreferenceConditional: 1103case RegexNodeKind.ExpressionConditional: 1104int branchStart = node.Kind is RegexNodeKind.BackreferenceConditional ? 0 : 1; 1113case RegexNodeKind.Backreference: 1138while (node.Kind is RegexNodeKind.Atomic or RegexNodeKind.Capture) 1142if (node.Kind != RegexNodeKind.Concatenate) 1155while (firstChild.Kind is RegexNodeKind.Atomic or RegexNodeKind.Capture) 1159if (firstChild.Kind is not (RegexNodeKind.Setloop or RegexNodeKind.Setloopatomic or RegexNodeKind.Setlazy) || firstChild.N != int.MaxValue) 1167if (nextChild.Kind == RegexNodeKind.UpdateBumpalong) 1224while ((nextChild.Kind is RegexNodeKind.Atomic or RegexNodeKind.Capture or RegexNodeKind.Concatenate) || 1225(nextChild.Kind is RegexNodeKind.Loop or RegexNodeKind.Lazyloop && nextChild.M >= 1)) 1233(nextChild.Kind is RegexNodeKind.Set || nextChild.M >= 1)) 1279case RegexNodeKind.PositiveLookaround: 1284case RegexNodeKind.Bol: 1285case RegexNodeKind.Eol: 1286case RegexNodeKind.Beginning: 1287case RegexNodeKind.Start: 1288case RegexNodeKind.EndZ: 1289case RegexNodeKind.End: 1290case RegexNodeKind.Boundary: 1291case RegexNodeKind.ECMABoundary: 1292case RegexNodeKind.NegativeLookaround: 1293case RegexNodeKind.Empty: 1297case RegexNodeKind.Atomic: 1298case RegexNodeKind.Capture: 1303case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.M >= 1: 1309case RegexNodeKind.Concatenate: 1330public static RegexNodeKind FindLeadingAnchor(RegexNode node) => 1334public static RegexNodeKind FindTrailingAnchor(RegexNode node) => 1338private static RegexNodeKind FindLeadingOrTrailingAnchor(RegexNode node, bool leading) 1344return RegexNodeKind.Unknown; 1351case RegexNodeKind.Bol: 1352case RegexNodeKind.Eol: 1353case RegexNodeKind.Beginning: 1354case RegexNodeKind.Start: 1355case RegexNodeKind.EndZ: 1356case RegexNodeKind.End: 1360case RegexNodeKind.Atomic: 1361case RegexNodeKind.Capture: 1362case RegexNodeKind.Loop or RegexNodeKind.Lazyloop when leading && node.M >= 1: 1363case RegexNodeKind.PositiveLookaround when leading && (node.Options & RegexOptions.RightToLeft) == 0: 1373case RegexNodeKind.Concatenate: 1380RegexNodeKind bestAnchorFound = RegexNodeKind.Unknown; 1388case RegexNodeKind.Empty or RegexNodeKind.NegativeLookaround: 1389case RegexNodeKind.PositiveLookaround when ((node.Options | tmpChild.Options) & RegexOptions.RightToLeft) != 0: 1390case RegexNodeKind.Boundary or RegexNodeKind.ECMABoundary or RegexNodeKind.NonBoundary or RegexNodeKind.NonECMABoundary: 1394case RegexNodeKind.PositiveLookaround: 1416if (node.Child(i).Kind is not (RegexNodeKind.Empty or RegexNodeKind.PositiveLookaround or RegexNodeKind.NegativeLookaround)) 1424if (bestAnchorFound is not RegexNodeKind.Unknown) 1446static RegexNodeKind ChooseBetterAnchor(RegexNodeKind anchor1, RegexNodeKind anchor2) 1449anchor1 == RegexNodeKind.Unknown ? anchor2 : 1450anchor2 == RegexNodeKind.Unknown ? anchor1 : 1454static int RankAnchorQuality(RegexNodeKind node) => 1457RegexNodeKind.Beginning => 3, 1458RegexNodeKind.Start => 3, 1459RegexNodeKind.End => 3, 1460RegexNodeKind.EndZ => 3, 1462RegexNodeKind.Bol => 2, 1463RegexNodeKind.Eol => 2, 1465RegexNodeKind.Boundary => 1, 1466RegexNodeKind.ECMABoundary => 1, 1472static bool IsBestAnchor(RegexNodeKind anchor) => 1474anchor is RegexNodeKind.Beginning or RegexNodeKind.Start or RegexNodeKind.End or RegexNodeKind.EndZ; 1477case RegexNodeKind.Alternate: 1481RegexNodeKind anchor = FindLeadingOrTrailingAnchor(node.Child(0), leading); 1482if (anchor == RegexNodeKind.Unknown) 1484return RegexNodeKind.Unknown; 1494return RegexNodeKind.Unknown; 1504return RegexNodeKind.Unknown;
System\Text\RegularExpressions\RegexReplacement.cs (4)
36Debug.Assert(concat.Kind == RegexNodeKind.Concatenate, $"Expected Concatenate, got {concat.Kind}"); 50case RegexNodeKind.Multi: 54case RegexNodeKind.One: 58case RegexNodeKind.Backreference:
System\Text\RegularExpressions\RegexTreeAnalyzer.cs (16)
59case RegexNodeKind.Atomic: 60case RegexNodeKind.NegativeLookaround: 61case RegexNodeKind.PositiveLookaround: 66case RegexNodeKind.Capture: 71case RegexNodeKind.Loop: 72case RegexNodeKind.Lazyloop: 90RegexNodeKind.Atomic or RegexNodeKind.NegativeLookaround or RegexNodeKind.PositiveLookaround => true, 94RegexNodeKind.Alternate or RegexNodeKind.BackreferenceConditional or RegexNodeKind.ExpressionConditional => true, 97RegexNodeKind.Capture => true, 101RegexNodeKind.Concatenate => i == childCount - 1, 107RegexNodeKind.Loop or RegexNodeKind.Lazyloop when node.N == 1 => true,
System\Text\RegularExpressions\RegexWriter.cs (56)
14private const RegexNodeKind BeforeChild = (RegexNodeKind)64; 15private const RegexNodeKind AfterChild = (RegexNodeKind)128; 201private void EmitFragment(RegexNodeKind nodeType, RegexNode node, int curIndex) 215case RegexNodeKind.Concatenate | BeforeChild: 216case RegexNodeKind.Concatenate | AfterChild: 217case RegexNodeKind.Empty: 220case RegexNodeKind.Alternate | BeforeChild: 228case RegexNodeKind.Alternate | AfterChild: 247case RegexNodeKind.BackreferenceConditional | BeforeChild: 260case RegexNodeKind.BackreferenceConditional | AfterChild: 278case RegexNodeKind.ExpressionConditional | BeforeChild: 290case RegexNodeKind.ExpressionConditional | AfterChild: 311case RegexNodeKind.Loop | BeforeChild: 312case RegexNodeKind.Lazyloop | BeforeChild: 327case RegexNodeKind.Loop | AfterChild: 328case RegexNodeKind.Lazyloop | AfterChild: 331int Lazy = (nodeType - (RegexNodeKind.Loop | AfterChild)); 343case RegexNodeKind.Capture | BeforeChild: 347case RegexNodeKind.Capture | AfterChild: 351case RegexNodeKind.PositiveLookaround | BeforeChild: 356case RegexNodeKind.PositiveLookaround | AfterChild: 361case RegexNodeKind.NegativeLookaround | BeforeChild: 367case RegexNodeKind.NegativeLookaround | AfterChild: 373case RegexNodeKind.Atomic | BeforeChild: 377case RegexNodeKind.Atomic | AfterChild: 381case RegexNodeKind.One: 382case RegexNodeKind.Notone: 386case RegexNodeKind.Notoneloop: 387case RegexNodeKind.Notoneloopatomic: 388case RegexNodeKind.Notonelazy: 389case RegexNodeKind.Oneloop: 390case RegexNodeKind.Oneloopatomic: 391case RegexNodeKind.Onelazy: 394Emit(((node.Kind is RegexNodeKind.Oneloop or RegexNodeKind.Oneloopatomic or RegexNodeKind.Onelazy) ? 403case RegexNodeKind.Setloop: 404case RegexNodeKind.Setloopatomic: 405case RegexNodeKind.Setlazy: 419case RegexNodeKind.Multi: 423case RegexNodeKind.Set: 427case RegexNodeKind.Backreference: 431case RegexNodeKind.Nothing: 432case RegexNodeKind.Bol: 433case RegexNodeKind.Eol: 434case RegexNodeKind.Boundary: 435case RegexNodeKind.NonBoundary: 436case RegexNodeKind.ECMABoundary: 437case RegexNodeKind.NonECMABoundary: 438case RegexNodeKind.Beginning: 439case RegexNodeKind.Start: 440case RegexNodeKind.EndZ: 441case RegexNodeKind.End: 442case RegexNodeKind.UpdateBumpalong:
System\Text\RegularExpressions\Symbolic\RegexNodeConverter.cs (49)
57case RegexNodeKind.One: 61case RegexNodeKind.Notone: 65case RegexNodeKind.Set: 69case RegexNodeKind.Multi: 84case RegexNodeKind.Concatenate: 85case RegexNodeKind.Alternate: 86case RegexNodeKind.Loop: 87case RegexNodeKind.Lazyloop: 88case RegexNodeKind.Capture when node.N == -1: // N == -1 because balancing groups (which have N >= 0) aren't supported 106case RegexNodeKind.Oneloop: 107case RegexNodeKind.Onelazy: 108case RegexNodeKind.Notoneloop: 109case RegexNodeKind.Notonelazy: 117result.AddLast(_builder.CreateLoop(_builder.CreateSingleton(bdd), node.Kind is RegexNodeKind.Onelazy or RegexNodeKind.Notonelazy, node.M, node.N)); 121case RegexNodeKind.Setloop: 122case RegexNodeKind.Setlazy: 128result.AddLast(_builder.CreateLoop(_builder.CreateSingleton(setBdd), node.Kind == RegexNodeKind.Setlazy, node.M, node.N)); 132case RegexNodeKind.Empty: 133case RegexNodeKind.UpdateBumpalong: // UpdateBumpalong is a directive relevant only to backtracking and can be ignored just like Empty 136case RegexNodeKind.Nothing: 142case RegexNodeKind.Beginning: 146case RegexNodeKind.Bol: 151case RegexNodeKind.End: // \z anchor 155case RegexNodeKind.EndZ: // \Z anchor 160case RegexNodeKind.Eol: 165case RegexNodeKind.Boundary: 170case RegexNodeKind.NonBoundary: 180RegexNodeKind.Atomic or RegexNodeKind.Setloopatomic or RegexNodeKind.Oneloopatomic or RegexNodeKind.Notoneloopatomic => SR.ExpressionDescription_AtomicSubexpressions, 181RegexNodeKind.Backreference => SR.ExpressionDescription_Backreference, 182RegexNodeKind.BackreferenceConditional => SR.ExpressionDescription_Conditional, 183RegexNodeKind.Capture => SR.ExpressionDescription_BalancingGroup, 184RegexNodeKind.ExpressionConditional => SR.ExpressionDescription_IfThenElse, 185RegexNodeKind.NegativeLookaround => SR.ExpressionDescription_NegativeLookaround, 186RegexNodeKind.PositiveLookaround => SR.ExpressionDescription_PositiveLookaround, 187RegexNodeKind.Start => SR.ExpressionDescription_ContiguousMatches, 195string description = $"Unexpected ({nameof(RegexNodeKind)}: {node.Kind})"; 211case RegexNodeKind.Concatenate: 221case RegexNodeKind.Alternate: 250case RegexNodeKind.Loop: 251case RegexNodeKind.Lazyloop: 260result.AddLast(_builder.CreateLoop(body, node.Kind == RegexNodeKind.Lazyloop, node.M, node.N)); 267Debug.Assert(node.Kind == RegexNodeKind.Capture && node.N == -1); 285Debug.Assert(rootResult.Count == 1 || root.Kind == RegexNodeKind.Concatenate || root.Kind == RegexNodeKind.Capture); 312Debug.Assert(node.Kind == RegexNodeKind.Set);
System\Text\RegularExpressions\Symbolic\SymbolicRegexKind.cs (16)
9/// <summary>An empty node that matches a zero-width input (e.g. <see cref="RegexNodeKind.Empty"/>).</summary> 11/// <summary>A node that matches a single character (i.e. <see cref="RegexNodeKind.One"/>, <see cref="RegexNodeKind.Notone"/>, or <see cref="RegexNodeKind.Set"/>).</summary> 13/// <summary>A node that matches a sequence of nodes (i.e. <see cref="RegexNodeKind.Concatenate"/>).</summary> 15/// <summary>A node that matches a loop (e.g. <see cref="RegexNodeKind.Loop"/>, <see cref="RegexNodeKind.Lazyloop"/>, <see cref="RegexNodeKind.Setloop"/>, etc.).</summary> 17/// <summary>A node that matches if any of its nodes match and that matches them in a fixed order that mirrors how the backtracking engines operate (e.g. <see cref="RegexNodeKind.Alternate"/>).</summary> 20/// <summary>A node that represents a beginning anchor (i.e. <see cref="RegexNodeKind.Beginning"/>).</summary> 22/// <summary>A node that represents an ending anchor (i.e. <see cref="RegexNodeKind.End"/>).</summary> 24/// <summary>A node that represents an ending \Z anchor (i.e. <see cref="RegexNodeKind.EndZ"/>).</summary> 28/// <summary>A node that represents a beginning-of-line anchor (i.e. <see cref="RegexNodeKind.Bol"/>).</summary> 30/// <summary>A node that represents a end-of-line anchor (i.e. <see cref="RegexNodeKind.Eol"/>).</summary> 32/// <summary>A node that represents a word boundary anchor (i.e. <see cref="RegexNodeKind.Boundary"/>).</summary> 34/// <summary>A node that represents a word non-boundary anchor (i.e. <see cref="RegexNodeKind.NonBoundary"/>).</summary>
System\Text\RegularExpressions\Symbolic\SymbolicRegexMatcher.cs (1)
211findOptimizations.LeadingAnchor is not RegexNodeKind.Beginning)