Skip to content

Commit e21abfe

Browse files
committed
wip: broken
1 parent df63ffa commit e21abfe

File tree

10 files changed

+166
-127
lines changed

10 files changed

+166
-127
lines changed

Sources/VariadicsGenerator/VariadicsGenerator.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ struct VariadicsGenerator: ParsableCommand {
513513
output("""
514514
extension \(altBuilderName) {
515515
public static func buildBlock<\(genericParams)>(_ regex: R) -> \(regexTypeName)<(W, \(resultCaptures))> \(whereClause) {
516-
.init(node: .alternation([regex.regex.root]))
516+
.init(node: .orderedChoice([regex.regex.root]))
517517
}
518518
}
519519
@@ -541,13 +541,13 @@ struct VariadicsGenerator: ParsableCommand {
541541
public func capture<\(genericParams)>(
542542
_ component: R
543543
) -> \(regexTypeName)<\(rawNewMatchType)> \(whereClause) {
544-
.init(node: .group(.capture, component.regex.root))
544+
.init(node: .capture(name: nil, nil, component.regex.root))
545545
}
546546
547547
public func capture<\(genericParams)>(
548548
_ component: R, as reference: Reference<W>
549549
) -> \(regexTypeName)<\(rawNewMatchType)> \(whereClause) {
550-
.init(node: .group(.capture, component.regex.root, reference.id))
550+
.init(node: .capture(name: nil, reference.id, component.regex.root))
551551
}
552552
553553
public func capture<\(genericParams), NewCapture>(
@@ -633,14 +633,14 @@ struct VariadicsGenerator: ParsableCommand {
633633
public func capture<\(genericParams)>(
634634
@\(concatBuilderName) _ component: () -> R
635635
) -> \(regexTypeName)<\(rawNewMatchType)> \(whereClause) {
636-
.init(node: .group(.capture, component().regex.root))
636+
.init(node: .capture(name: nil, nil, component().regex.root))
637637
}
638638
639639
public func capture<\(genericParams)>(
640640
as reference: Reference<W>,
641641
@\(concatBuilderName) _ component: () -> R
642642
) -> \(regexTypeName)<\(rawNewMatchType)> \(whereClause) {
643-
.init(node: .group(.capture, component().regex.root, reference.id))
643+
.init(node: .capture(name: nil, reference.id, component().regex.root))
644644
}
645645
646646
public func capture<\(genericParams), NewCapture>(

Sources/_MatchingEngine/Regex/Parse/CaptureStructure.swift

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ extension CaptureStructure {
4242
}
4343

4444
extension CaptureStructure.Constructor {
45+
private func atom(
46+
_ name: String? = nil , _ type: AnyType? = nil
47+
) -> CaptureStructure {
48+
.atom(name: name, type: type)
49+
}
50+
4551
public mutating func alternating<C: Collection>(
4652
_ children: C
4753
) -> CaptureStructure where C.Element: _TreeNode {
@@ -59,16 +65,18 @@ extension CaptureStructure.Constructor {
5965
}
6066

6167
public mutating func grouping<T: _TreeNode>(
62-
_ child: T, as kind: AST.Group.Kind
68+
_ child: T,
69+
as kind: AST.Group.Kind,
70+
withType type: AnyType? = nil
6371
) -> CaptureStructure {
6472
let innerCaptures = child._captureStructure(&self)
6573
switch kind {
6674
case .capture:
67-
return .atom() + innerCaptures
75+
return atom(nil, type) + innerCaptures
6876
case .namedCapture(let name):
69-
return .atom(name: name.value) + innerCaptures
77+
return atom(name.value, type) + innerCaptures
7078
case .balancedCapture(let b):
71-
return .atom(name: b.name?.value) + innerCaptures
79+
return atom(b.name?.value, type) + innerCaptures
7280
default:
7381
precondition(!kind.isCapturing)
7482
return innerCaptures
@@ -81,32 +89,25 @@ extension CaptureStructure.Constructor {
8189
withTransform transform: CaptureTransform
8290
) -> CaptureStructure {
8391
let innerCaptures = child._captureStructure(&self)
92+
let type = AnyType(transform.resultType)
8493
switch kind {
8594
case .capture:
86-
return .atom(type: AnyType(transform.resultType)) + innerCaptures
95+
return atom(nil, type) + innerCaptures
8796
case .namedCapture(let name):
88-
return .atom(name: name.value, type: AnyType(transform.resultType))
89-
+ innerCaptures
97+
return atom(name.value, type) + innerCaptures
98+
case .balancedCapture(let b):
99+
return atom(b.name?.value, type) + innerCaptures
90100
default:
91101
return innerCaptures
92102
}
93103
}
94104

95-
public mutating func grouping<T: _TreeNode>(
105+
public mutating func capturing<T: _TreeNode>(
106+
name: String?,
96107
_ child: T,
97-
as kind: AST.Group.Kind,
98-
withType type: AnyType
108+
withType type: AnyType? = nil
99109
) -> CaptureStructure {
100-
let innerCaptures = child._captureStructure(&self)
101-
switch kind {
102-
case .capture:
103-
return .atom(type: type) + innerCaptures
104-
case .namedCapture(let name):
105-
return .atom(name: name.value, type: type)
106-
+ innerCaptures
107-
default:
108-
return innerCaptures
109-
}
110+
atom(name, type) + child._captureStructure(&self)
110111
}
111112

112113
// TODO: We'll likely want/need a generalization of

Sources/_StringProcessing/ByteCodeGen.swift

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -299,28 +299,34 @@ extension Compiler.ByteCodeGen {
299299
}
300300
}
301301

302-
mutating func emitGroup(
302+
mutating func emitCapture(
303+
_ name: String?,
304+
_ refId: ReferenceID?,
305+
_ child: DSLTree.Node
306+
) throws -> CaptureRegister {
307+
let cap = builder.makeCapture(id: refId)
308+
switch child {
309+
case .matcher(_, let m):
310+
emitMatcher(m, into: cap)
311+
312+
default:
313+
builder.buildBeginCapture(cap)
314+
try emitNode(child)
315+
builder.buildEndCapture(cap)
316+
return cap
317+
}
318+
return cap
319+
}
320+
321+
mutating func emitNoncapturingGroup(
303322
_ kind: AST.Group.Kind,
304-
_ child: DSLTree.Node,
305-
_ referenceID: ReferenceID?
323+
_ child: DSLTree.Node
306324
) throws -> CaptureRegister? {
307-
guard kind.isCapturing || referenceID == nil else {
308-
throw Unreachable("Reference ID shouldn't exist for non-capturing groups")
309-
}
325+
assert(!kind.isCapturing)
310326

311327
options.beginScope()
312328
defer { options.endScope() }
313329

314-
// If we have a strong type, write result directly into
315-
// the capture register.
316-
//
317-
// FIXME: Unify with .groupTransform
318-
if kind.isCapturing, case let .matcher(_, m) = child {
319-
let cap = builder.makeCapture(id: referenceID)
320-
emitMatcher(m, into: cap)
321-
return cap
322-
}
323-
324330
if let lookaround = kind.lookaroundKind {
325331
try emitLookaround(lookaround, child)
326332
return nil
@@ -331,12 +337,8 @@ extension Compiler.ByteCodeGen {
331337
.lookbehind, .negativeLookbehind:
332338
throw Unreachable("TODO: reason")
333339

334-
case .capture, .namedCapture:
335-
let cap = builder.makeCapture(id: referenceID)
336-
builder.buildBeginCapture(cap)
337-
try emitNode(child)
338-
builder.buildEndCapture(cap)
339-
return cap
340+
case .capture, .namedCapture, .balancedCapture:
341+
throw Unreachable("These should produce a capture node")
340342

341343
case .changeMatchingOptions(let optionSequence, _):
342344
options.apply(optionSequence)
@@ -565,8 +567,11 @@ extension Compiler.ByteCodeGen {
565567
try emitConcatenationComponent(child)
566568
}
567569

568-
case let .group(kind, child, referenceID):
569-
_ = try emitGroup(kind, child, referenceID)
570+
case let .capture(name, ref, child):
571+
_ = try emitCapture(name, ref, child)
572+
573+
case let .nonCapturingGroup(kind, child):
574+
try emitNoncapturingGroup(kind, child)
570575

571576
case .conditional:
572577
throw Unsupported("Conditionals")
@@ -606,20 +611,25 @@ extension Compiler.ByteCodeGen {
606611
try emitNode(n)
607612

608613
case let .groupTransform(kind, child, t, referenceID):
609-
guard let cap = try emitGroup(kind, child, referenceID) else {
610-
assertionFailure("""
611-
What does it mean to not have a capture to transform?
612-
""")
613-
return
614-
}
615-
616-
// FIXME: Is this how we want to do it?
617-
let transform = builder.makeTransformFunction {
618-
input, range in
619-
t(input[range])
620-
}
621-
622-
builder.buildTransformCapture(cap, transform)
614+
fatalError()
615+
616+
// // TODO: convert this to just a value-transform node
617+
//
618+
//
619+
// guard let cap = try emitGroup(kind, child, referenceID) else {
620+
// assertionFailure("""
621+
// What does it mean to not have a capture to transform?
622+
// """)
623+
// return
624+
// }
625+
//
626+
// // FIXME: Is this how we want to do it?
627+
// let transform = builder.makeTransformFunction {
628+
// input, range in
629+
// t(input[range])
630+
// }
631+
//
632+
// builder.buildTransformCapture(cap, transform)
623633

624634
case .absentFunction:
625635
throw Unsupported("absent function")

Sources/_StringProcessing/ConsumerInterface.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ extension DSLTree.Node {
3636
case let .convertedRegexLiteral(n, _):
3737
return try n.generateConsumer(opts)
3838

39-
case .orderedChoice, .conditional, .concatenation, .group,
39+
case .orderedChoice, .conditional, .concatenation,
40+
.capture, .nonCapturingGroup,
4041
.quantification, .trivia, .empty,
4142
.groupTransform, .absentFunction: return nil
4243

Sources/_StringProcessing/PrintAsPattern.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,18 @@ extension PrettyPrinter {
8787
}
8888
}
8989

90-
case let .group(kind, child, referenceID):
90+
case let .nonCapturingGroup(kind, child):
9191
let kind = kind._patternBase
92-
let refIDString = referenceID.map { ", referenceID: \($0)" } ?? ""
93-
printBlock("Group(\(kind)\(refIDString)") { printer in
92+
printBlock("Group(\(kind))") { printer in
93+
printer.printAsPattern(convertedFromAST: child)
94+
}
95+
96+
case let .capture(name, _, child):
97+
var cap = "capture"
98+
if let n = name {
99+
cap += "(\(n))"
100+
}
101+
printBlock(cap) { printer in
94102
printer.printAsPattern(convertedFromAST: child)
95103
}
96104

Sources/_StringProcessing/RegexDSL/ASTConversion.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ extension AST.Node {
4444
}
4545

4646
// Convert the top-level node without wrapping
47-
func convert() -> DSLTree.Node {
47+
func convert() throws -> DSLTree.Node {
4848
switch self {
4949
case let .alternation(v):
5050
let children = v.children.map(\.dslTreeNode)
@@ -103,7 +103,16 @@ extension AST.Node {
103103

104104
case let .group(v):
105105
let child = v.child.dslTreeNode
106-
return .group(v.kind.value, child)
106+
switch v.kind.value {
107+
case .capture:
108+
return .capture(name: nil, nil, child)
109+
case .namedCapture(let name):
110+
return .capture(name: name.value, nil, child)
111+
case .balancedCapture:
112+
throw Unsupported("TODO: balanced captures")
113+
default:
114+
return .nonCapturingGroup(v.kind.value, child)
115+
}
107116

108117
case let .conditional(v):
109118
let trueBranch = v.trueBranch.dslTreeNode
@@ -137,7 +146,8 @@ extension AST.Node {
137146
}
138147
}
139148

140-
let converted = convert()
149+
// FIXME: make total function again
150+
let converted = try! convert()
141151
return wrap(converted)
142152
}
143153
}

Sources/_StringProcessing/RegexDSL/Anchor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ public func lookahead<R: RegexComponent>(
110110
negative: Bool = false,
111111
@RegexComponentBuilder _ content: () -> R
112112
) -> Regex<R.Match> {
113-
Regex(node: .group(negative ? .negativeLookahead : .lookahead, content().regex.root))
113+
Regex(node: .nonCapturingGroup(negative ? .negativeLookahead : .lookahead, content().regex.root))
114114
}
115115

116116
public func lookahead<R: RegexComponent>(
117117
_ component: R,
118118
negative: Bool = false
119119
) -> Regex<R.Match> {
120-
Regex(node: .group(negative ? .negativeLookahead : .lookahead, component.regex.root))
120+
Regex(node: .nonCapturingGroup(negative ? .negativeLookahead : .lookahead, component.regex.root))
121121
}

Sources/_StringProcessing/RegexDSL/DSLTree.swift

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ extension DSLTree {
3333
/// ... ...
3434
case concatenation([Node])
3535

36-
/// Match a subpattern / group
36+
/// Capture the result of a subpattern
3737
///
38-
/// (...)
39-
case group(AST.Group.Kind, Node, ReferenceID? = nil)
38+
/// (...), (?<name>...)
39+
case capture(name: String?, ReferenceID?, Node)
40+
41+
/// Match a (non-capturing) subpattern / group
42+
case nonCapturingGroup(AST.Group.Kind, Node)
4043

4144
// TODO: Consider splitting off grouped conditions, or have
4245
// our own kind
@@ -174,9 +177,10 @@ extension DSLTree.Node {
174177
// Treat this transparently
175178
return n.children
176179

177-
case let .group(_, n, _): return [n]
180+
case let .capture(_, _, n): return [n]
181+
case let .nonCapturingGroup(_, n): return [n]
178182
case let .groupTransform(_, n, _, _): return [n]
179-
case let .quantification(_, _, n): return [n]
183+
case let .quantification(_, _, n): return [n]
180184

181185
case let .conditional(_, t, f): return [t,f]
182186

@@ -236,18 +240,17 @@ extension DSLTree {
236240
extension DSLTree.Node {
237241
var hasCapture: Bool {
238242
switch self {
239-
case let .group(k, _, _) where k.isCapturing,
240-
let .groupTransform(k, _, _, _) where k.isCapturing:
243+
case .capture:
241244
return true
245+
case let .regexLiteral(re):
246+
return re.hasCapture
242247
case let .convertedRegexLiteral(n, re):
243248
assert(n.hasCapture == re.hasCapture)
244249
return n.hasCapture
245-
case let .regexLiteral(re):
246-
return re.hasCapture
250+
247251
default:
248-
break
252+
return self.children?.any(\.hasCapture) ?? false
249253
}
250-
return self.children?.any(\.hasCapture) ?? false
251254
}
252255
}
253256

@@ -269,11 +272,15 @@ extension DSLTree.Node {
269272
case let .concatenation(children):
270273
return constructor.concatenating(children)
271274

272-
case let .group(kind, child, _):
275+
case let .capture(name, _, child):
273276
if let type = child.matcherCaptureType {
274-
return constructor.grouping(
275-
child, as: kind, withType: type)
277+
return constructor.capturing(
278+
name: name, child, withType: type)
276279
}
280+
return constructor.capturing(name: name, child)
281+
282+
case let .nonCapturingGroup(kind, child):
283+
assert(!kind.isCapturing)
277284
return constructor.grouping(child, as: kind)
278285

279286
case let .groupTransform(kind, child, transform, _):

0 commit comments

Comments
 (0)