@@ -92,10 +92,10 @@ extension Processor {
92
92
isScalarSemantics: isScalarSemantics)
93
93
}
94
94
95
- case . builtin :
95
+ case . builtinCC :
96
96
if isZeroOrMore {
97
97
matchResult = input. matchZeroOrMoreBuiltinCC (
98
- payload. builtin ,
98
+ payload. builtinCC ,
99
99
at: currentPosition,
100
100
limitedBy: end,
101
101
produceSavePointRange: produceSavePointRange,
@@ -104,7 +104,7 @@ extension Processor {
104
104
isScalarSemantics: isScalarSemantics)
105
105
} else if isOneOrMore {
106
106
matchResult = input. matchOneOrMoreBuiltinCC (
107
- payload. builtin ,
107
+ payload. builtinCC ,
108
108
at: currentPosition,
109
109
limitedBy: end,
110
110
produceSavePointRange: produceSavePointRange,
@@ -113,7 +113,7 @@ extension Processor {
113
113
isScalarSemantics: isScalarSemantics)
114
114
} else {
115
115
matchResult = input. matchQuantifiedBuiltinCC (
116
- payload. builtin ,
116
+ payload. builtinCC ,
117
117
at: currentPosition,
118
118
limitedBy: end,
119
119
minMatches: minMatches,
@@ -158,6 +158,11 @@ extension String {
158
158
) -> Index ?
159
159
) -> ( next: Index , savePointRange: Range < Index > ? ) ? {
160
160
var currentPosition = currentPosition
161
+
162
+ // The range of backtracking positions to try. For zero-or-more, starts
163
+ // before any match happens. Always ends before the final match, since
164
+ // the final match is what is tried without backtracking. An empty range
165
+ // is valid and means a single backtracking position at rangeStart.
161
166
var rangeStart = currentPosition
162
167
var rangeEnd = currentPosition
163
168
@@ -171,6 +176,12 @@ extension String {
171
176
}
172
177
numMatches &+= 1
173
178
if numMatches == minMatches {
179
+ // For this loop iteration, rangeEnd will actually trail rangeStart by
180
+ // a single match position. Next iteration, they will be equal
181
+ // (empty range denoting a single backtracking point). Note that we
182
+ // only ever return a range if we have exceeded `minMatches`; if we
183
+ // exactly mach `minMatches` there is no backtracking positions to
184
+ // remember.
174
185
rangeStart = next
175
186
}
176
187
rangeEnd = currentPosition
@@ -183,20 +194,22 @@ extension String {
183
194
}
184
195
185
196
guard produceSavePointRange && numMatches > minMatches else {
186
- // Consumed no input, no point saved
197
+ // No backtracking positions to try
187
198
return ( currentPosition, nil )
188
199
}
189
200
assert ( rangeStart <= rangeEnd)
190
201
191
- // NOTE: We can't assert that rangeEnd trails currentPosition by one
192
- // position, because newline-sequence in scalar semantic mode still
202
+ // NOTE: We can't assert that rangeEnd trails currentPosition by exactly
203
+ // one position, because newline-sequence in scalar semantic mode still
193
204
// matches two scalars
194
205
195
206
return ( currentPosition, rangeStart..< rangeEnd)
196
207
}
197
208
198
- /// NOTE: [Zero|One]OrMore overloads are to specialize the inlined run loop,
199
- /// which has a substantive perf impact (especially for zero-or-more)
209
+ // NOTE: [Zero|One]OrMore overloads are to specialize the inlined run loop,
210
+ // which has a perf impact. At the time of writing this, 10% for
211
+ // zero-or-more and 5% for one-or-more improvement, which could very well
212
+ // be much higher if/when the inner match functions are made faster.
200
213
201
214
fileprivate func matchZeroOrMoreASCIIBitset(
202
215
_ asciiBitset: ASCIIBitset ,
0 commit comments