Skip to content

Commit d1aa698

Browse files
committed
Drop arrays and unzip tuples for quantified captures.
To bridge the typing gap between regex literals and regex builder, this patch introduces the following changes: 1. Repeating quantifiers no longer produce an array capture. Instead, produce an optional capture when the lower bound is `0`, otherwise an atom capture. After matching, this capture corresponds to the last occurrence in the match. A history-saving quantifier variant will be introduced at a later time. 2. Applying a quantifier on a tuple-capturing regex will map quantification onto every tuple element, resulting in a tuple of quantified captures (unzipped). ----- ```swift let literal = /a((b)(b)+)*(c)+(d)?/ // 0 ^~~~~~~~~~~~~~~~ // 1 ^~~~~~ // 2 ^~~ // 3 ^~~ // 4 ^~~ // 5 ^~~ // => Regex<(Substring, Substring?, Substring?, Substring?, Substring, Substring?)> // Equivalent regex using regex builder: let dsl = Regex { // 0 "a" zeroOrMore { capture { // 1 capture { // 2 "b" } oneOrMore { capture { // 3 "b" } } } } oneOrMore { capture { // 4 "c" } } optionally { capture { // 5 "d" } } } // => Regex<(Substring, Substring?, Substring?, Substring?, Substring, Substring?)> ```
1 parent ff635c6 commit d1aa698

File tree

7 files changed

+208
-198
lines changed

7 files changed

+208
-198
lines changed

Sources/VariadicsGenerator/VariadicsGenerator.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ struct VariadicsGenerator: ParsableCommand {
294294
var operatorName: String {
295295
switch self {
296296
case .zeroOrOne: return ".?"
297-
case .zeroOrMore: return ".+"
298-
case .oneOrMore: return ".*"
297+
case .zeroOrMore: return ".*"
298+
case .oneOrMore: return ".+"
299299
}
300300
}
301301

@@ -320,16 +320,16 @@ struct VariadicsGenerator: ParsableCommand {
320320
result += "Component: \(regexProtocolName)"
321321
return result
322322
}()
323-
let captures = (0..<arity).map { "C\($0)" }.joined(separator: ", ")
324-
let capturesTupled = arity == 1 ? captures : "(\(captures))"
323+
let captures = (0..<arity).map { "C\($0)" }
324+
let capturesJoined = captures.joined(separator: ", ")
325325
let whereClause: String = arity == 0 ? "" :
326-
"where Component.Match == (W, \(captures))"
326+
"where Component.Match == (W, \(capturesJoined))"
327327
let quantifiedCaptures: String = {
328328
switch kind {
329-
case .zeroOrOne:
330-
return "\(capturesTupled)?"
331-
case .zeroOrMore, .oneOrMore:
332-
return "[\(capturesTupled)]"
329+
case .zeroOrOne, .zeroOrMore:
330+
return captures.map { "\($0)?" }.joined(separator: ", ")
331+
case .oneOrMore:
332+
return capturesJoined
333333
}
334334
}()
335335
let matchType = arity == 0 ? baseMatchTypeName : "(\(baseMatchTypeName), \(quantifiedCaptures))"

Sources/_MatchingEngine/Regex/Parse/CaptureStructure.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ extension CaptureStructure.Constructor {
4646
public mutating func alternating<C: Collection>(
4747
_ children: C
4848
) -> CaptureStructure where C.Element: _TreeNode {
49-
// assert(children.count > 1)
5049
return children.map {
5150
$0._captureStructure(&self)
5251
}.reduce(.empty, +)
@@ -113,17 +112,15 @@ extension CaptureStructure.Constructor {
113112
}
114113
let branchCaptures = trueBranch._captureStructure(&self) +
115114
falseBranch._captureStructure(&self)
116-
return captures + branchCaptures.map(
117-
CaptureStructure.optional)
115+
return captures + branchCaptures.map(CaptureStructure.optional)
118116
}
119117

120118
public mutating func quantifying<T: _TreeNode>(
121119
_ child: T, amount: AST.Quantification.Amount
122120
) -> CaptureStructure {
123-
return child._captureStructure(&self).map(
124-
amount == .zeroOrOne
125-
? CaptureStructure.optional
126-
: CaptureStructure.array)
121+
let result = child._captureStructure(&self)
122+
return amount.bounds.atLeast == 0
123+
? result.map(CaptureStructure.optional) : result
127124
}
128125

129126
// TODO: Will need to adjust for DSLTree support, and

0 commit comments

Comments
 (0)