Skip to content

Commit 203868f

Browse files
committed
Form ASCII bitsets for quoted sequences in character classes
1 parent 61007c0 commit 203868f

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
@@ -327,24 +327,25 @@ extension DSLTree.CustomCharacterClass.Member {
327327
_ opts: MatchingOptions,
328328
_ isInverted: Bool
329329
) -> DSLTree.CustomCharacterClass.AsciiBitset? {
330+
typealias Bitset = DSLTree.CustomCharacterClass.AsciiBitset
330331
switch self {
331332
case let .atom(a):
332333
if let val = a.singleScalarASCIIValue {
333-
return DSLTree.CustomCharacterClass.AsciiBitset(
334-
val,
335-
isInverted,
336-
opts.isCaseInsensitive
337-
)
334+
return Bitset(val, isInverted, opts.isCaseInsensitive)
338335
}
339336
case let .range(low, high):
340-
if let lowVal = low.singleScalarASCIIValue, let highVal = high.singleScalarASCIIValue {
341-
return DSLTree.CustomCharacterClass.AsciiBitset(
342-
low: lowVal,
343-
high: highVal,
344-
isInverted: isInverted,
345-
isCaseInsensitive: opts.isCaseInsensitive
346-
)
337+
if let lowVal = low.singleScalarASCIIValue,
338+
let highVal = high.singleScalarASCIIValue {
339+
return Bitset(low: lowVal, high: highVal, isInverted: isInverted,
340+
isCaseInsensitive: opts.isCaseInsensitive)
341+
}
342+
case .quotedLiteral(let str):
343+
var bitset = Bitset(isInverted: isInverted)
344+
for c in str {
345+
guard let ascii = c._singleScalarAsciiValue else { return nil }
346+
bitset = bitset.union(Bitset(ascii, isInverted, opts.isCaseInsensitive))
347347
}
348+
return bitset
348349
default:
349350
return nil
350351
}

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)