in Sources/_MatchingEngine/Regex/Parse/LexicalAnalysis.swift [535:588]
mutating func lexMatchingOption() throws -> AST.MatchingOption? {
typealias OptKind = AST.MatchingOption.Kind
let locOpt = try recordLoc { src -> OptKind? in
func advanceAndReturn(_ o: OptKind) -> OptKind {
src.advance()
return o
}
guard let c = src.peek() else { return nil }
switch c {
// PCRE options.
case "i": return advanceAndReturn(.caseInsensitive)
case "J": return advanceAndReturn(.allowDuplicateGroupNames)
case "m": return advanceAndReturn(.multiline)
case "n": return advanceAndReturn(.noAutoCapture)
case "s": return advanceAndReturn(.singleLine)
case "U": return advanceAndReturn(.reluctantByDefault)
case "x":
src.advance()
return src.tryEat("x") ? .extraExtended : .extended
// ICU options.
case "w": return advanceAndReturn(.unicodeWordBoundaries)
// Oniguruma options.
case "D": return advanceAndReturn(.asciiOnlyDigit)
case "P": return advanceAndReturn(.asciiOnlyPOSIXProps)
case "S": return advanceAndReturn(.asciiOnlySpace)
case "W": return advanceAndReturn(.asciiOnlyWord)
case "y":
src.advance()
try src.expect("{")
let opt: OptKind
if src.tryEat("w") {
opt = .textSegmentWordMode
} else {
try src.expect("g")
opt = .textSegmentGraphemeMode
}
try src.expect("}")
return opt
// Swift semantic level options
case "X": return advanceAndReturn(.graphemeClusterSemantics)
case "u": return advanceAndReturn(.unicodeScalarSemantics)
case "b": return advanceAndReturn(.byteSemantics)
default:
return nil
}
}
guard let locOpt = locOpt else { return nil }
return .init(locOpt.value, location: locOpt.location)
}