Skip to content

Commit 2095b85

Browse files
committed
Form ASCII bitsets for quoted sequences in character classes
1 parent dc90b1f commit 2095b85

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

Sources/_StringProcessing/ConsumerInterface.swift

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,24 +308,25 @@ extension DSLTree.CustomCharacterClass.Member {
308308
_ opts: MatchingOptions,
309309
_ isInverted: Bool
310310
) -> DSLTree.CustomCharacterClass.AsciiBitset? {
311+
typealias Bitset = DSLTree.CustomCharacterClass.AsciiBitset
311312
switch self {
312313
case let .atom(a):
313314
if let val = a.singleScalarASCIIValue {
314-
return DSLTree.CustomCharacterClass.AsciiBitset(
315-
val,
316-
isInverted,
317-
opts.isCaseInsensitive
318-
)
315+
return Bitset(val, isInverted, opts.isCaseInsensitive)
319316
}
320317
case let .range(low, high):
321-
if let lowVal = low.singleScalarASCIIValue, let highVal = high.singleScalarASCIIValue {
322-
return DSLTree.CustomCharacterClass.AsciiBitset(
323-
low: lowVal,
324-
high: highVal,
325-
isInverted: isInverted,
326-
isCaseInsensitive: opts.isCaseInsensitive
327-
)
318+
if let lowVal = low.singleScalarASCIIValue,
319+
let highVal = high.singleScalarASCIIValue {
320+
return Bitset(low: lowVal, high: highVal, isInverted: isInverted,
321+
isCaseInsensitive: opts.isCaseInsensitive)
322+
}
323+
case .quotedLiteral(let str):
324+
var bitset = Bitset(isInverted: isInverted)
325+
for c in str {
326+
guard let ascii = c._singleScalarAsciiValue else { return nil }
327+
bitset = bitset.union(Bitset(ascii, isInverted, opts.isCaseInsensitive))
328328
}
329+
return bitset
329330
default:
330331
return nil
331332
}

Tests/RegexTests/CompileTests.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,15 @@ extension RegexTests {
317317
semanticLevel: .unicodeScalar,
318318
contains: [.matchBitsetScalar],
319319
doesNotContain: [.matchBitset, .consumeBy])
320+
expectProgram(
321+
for: #"[\Qab\Ec]"#,
322+
contains: [.matchBitset],
323+
doesNotContain: [.consumeBy, .matchBitsetScalar])
324+
expectProgram(
325+
for: #"[\Qab\Ec]"#,
326+
semanticLevel: .unicodeScalar,
327+
contains: [.matchBitsetScalar],
328+
doesNotContain: [.matchBitset, .consumeBy])
320329
}
321330

322331
func testScalarOptimizeCompilation() {

0 commit comments

Comments
 (0)