Skip to content

Commit beaccab

Browse files
committed
Limit auto-possessification to single atom quantifiers
1 parent 01fa7c6 commit beaccab

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

Sources/_StringProcessing/Optimizations/AutoPossessification.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extension DSLList {
2424
switch atom {
2525
case .changeMatchingOptions(let seq):
2626
// Exit early if an atom changes the matching options.
27-
// TODO: Allow some/all options changes.
2827
if allowOptionsChanges {
2928
options.apply(seq.ast)
3029
return nil
@@ -143,15 +142,17 @@ extension DSLList {
143142
let quantPosition = position
144143
position += 1
145144

146-
// Do a search within this quantification's contents
147-
// FIXME: How to handle an inner quantification surfacing here?
148-
var innerPosition = position
149-
_ = autoPossessifyNextQuantification(&innerPosition, options: &options)
150-
151-
switch _requiredAtomImpl(&position, options: &options, allowOptionsChanges: false) {
152-
case .some(let atom?):
145+
// Limit auto-possessification to a single quantified atom, to avoid
146+
// issues of overlapped matches.
147+
guard position < nodes.count else {
148+
return nil
149+
}
150+
switch nodes[position] {
151+
case .atom(let atom) where atom.isMatchable:
153152
return (quantPosition, atom)
154-
case .none, .some(.none):
153+
default:
154+
var innerPosition = position
155+
_ = autoPossessifyNextQuantification(&innerPosition, options: &options)
155156
return nil
156157
}
157158

Tests/RegexTests/OptimizationTests.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import Testing
3131
}
3232

3333
@available(macOS 9999, *)
34-
@Test(arguments: [#/a+b/#, #/a*b/#, #/\w+\s/#, #/(?:a+b|b+a)/#, #/(?:(?:a+b)+b)/#, #/\d+a/#, #/a+A/#])
34+
@Test(arguments: [#/a+b/#, #/a*b/#, #/\w+\s/#, #/(?:a+b|b+a)/#, #/\d+a/#, #/a+A/#])
3535
func autoPossessify(pattern: Regex<Substring>) throws {
3636
var list = DSLList(tree: pattern.program.tree)
3737
list.autoPossessify()
@@ -49,7 +49,8 @@ import Testing
4949
@available(macOS 9999, *)
5050
@Test(arguments: [
5151
#/a?/#, #/a+a/#, #/a+(?:b|c)/#, #/(?:a+|b+)/#, #/[a]/#, #/a?a/#,
52-
#/(?i)a+A/#, #/(?i:a+A)/# // case insensitivity when checking exclusion
52+
#/(?i)a+A/#, #/(?i:a+A)/#, // case insensitivity when checking exclusion
53+
#/(?:(?:ab)+b)/#, // single atom quantifications only
5354
])
5455
func noAutoPossessify(pattern: Regex<Substring>) throws {
5556
var list = DSLList(tree: pattern.program.tree)

0 commit comments

Comments
 (0)