Skip to content

Commit 7ca9a9a

Browse files
committed
Update AST -> AST.Node
Fix places that are currently producing and consuming AST nodes to use `AST.Node` instead of `AST`. This requires adding entry-points for both `AST` and `AST.Node` for: - renderAsCanonical - printAsCanonical - printAsPattern - _render(in:)
1 parent f4a4c61 commit 7ca9a9a

23 files changed

+1722
-1681
lines changed

Sources/VariadicsGenerator/VariadicsGenerator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ struct VariadicsGenerator: ParsableCommand {
255255
outputForEach(
256256
0..<arity, separator: ", ", lineTerminator: ""
257257
) { i in
258-
"x\(i).\(patternProtocolRequirementName).ast"
258+
"x\(i).\(patternProtocolRequirementName).ast.root"
259259
}
260260
output("))\n")
261261
output(" }\n}\n\n")

Sources/_MatchingEngine/Regex/AST/AST.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ extension AST.Node {
9696
}
9797

9898
/// If this node is a parent node, access its children
99-
public var children: [AST]? {
99+
public var children: [AST.Node]? {
100100
return (_associatedValue as? _ASTParent)?.children
101101
}
102102

@@ -144,10 +144,10 @@ extension AST.Node {
144144
extension AST {
145145

146146
public struct Alternation: Hashable, _ASTNode {
147-
public let children: [AST]
147+
public let children: [AST.Node]
148148
public let pipes: [SourceLocation]
149149

150-
public init(_ mems: [AST], pipes: [SourceLocation]) {
150+
public init(_ mems: [AST.Node], pipes: [SourceLocation]) {
151151
// An alternation must have at least two branches (though the branches
152152
// may be empty AST nodes), and n - 1 pipes.
153153
precondition(mems.count >= 2)
@@ -163,10 +163,10 @@ extension AST {
163163
}
164164

165165
public struct Concatenation: Hashable, _ASTNode {
166-
public let children: [AST]
166+
public let children: [AST.Node]
167167
public let location: SourceLocation
168168

169-
public init(_ mems: [AST], _ location: SourceLocation) {
169+
public init(_ mems: [AST.Node], _ location: SourceLocation) {
170170
self.children = mems
171171
self.location = location
172172
}
@@ -218,16 +218,16 @@ extension AST {
218218
public enum Kind: Hashable {
219219
/// An absent repeater `(?~absent)`. This is equivalent to `(?~|absent|.*)`
220220
/// and therefore matches as long as the pattern `absent` is not matched.
221-
case repeater(AST)
221+
case repeater(AST.Node)
222222

223223
/// An absent expression `(?~|absent|expr)`, which defines an `absent`
224224
/// pattern which must not be matched against while the pattern `expr` is
225225
/// matched.
226-
case expression(absentee: AST, pipe: SourceLocation, expr: AST)
226+
case expression(absentee: AST.Node, pipe: SourceLocation, expr: AST.Node)
227227

228228
/// An absent stopper `(?~|absent)`, which prevents matching against
229229
/// `absent` until the end of the regex, or until it is cleared.
230-
case stopper(AST)
230+
case stopper(AST.Node)
231231

232232
/// An absent clearer `(?~|)` which cancels the effect of an absent
233233
/// stopper.

Sources/_MatchingEngine/Regex/AST/ASTProtocols.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ extension _ASTNode {
2828
}
2929

3030
protocol _ASTParent: _ASTNode {
31-
var children: [AST] { get }
31+
var children: [AST.Node] { get }
3232
}
3333

3434
extension AST.Concatenation: _ASTParent {}
3535
extension AST.Alternation: _ASTParent {}
3636

3737
extension AST.Group: _ASTParent {
38-
var children: [AST] { [child] }
38+
var children: [AST.Node] { [child] }
3939
}
4040
extension AST.Quantification: _ASTParent {
41-
var children: [AST] { [child] }
41+
var children: [AST.Node] { [child] }
4242
}
4343
extension AST.AbsentFunction: _ASTParent {
44-
var children: [AST] {
44+
var children: [AST.Node] {
4545
switch kind {
4646
case .repeater(let a), .stopper(let a): return [a]
4747
case .expression(let a, _, let c): return [a, c]

Sources/_MatchingEngine/Regex/AST/Atom.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ extension AST.Atom {
689689
}
690690
}
691691

692-
extension AST {
692+
extension AST.Node {
693693
public var literalStringValue: String? {
694694
switch self {
695695
case .atom(let a): return a.literalStringValue

Sources/_MatchingEngine/Regex/AST/Conditional.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ extension AST {
1414
public var location: SourceLocation
1515
public var condition: Condition
1616

17-
public var trueBranch: AST
17+
public var trueBranch: AST.Node
1818
public var pipe: SourceLocation?
19-
public var falseBranch: AST
19+
public var falseBranch: AST.Node
2020

2121
public init(
22-
_ condition: Condition, trueBranch: AST, pipe: SourceLocation?,
23-
falseBranch: AST, _ location: SourceLocation
22+
_ condition: Condition, trueBranch: AST.Node, pipe: SourceLocation?,
23+
falseBranch: AST.Node, _ location: SourceLocation
2424
) {
2525
self.location = location
2626
self.condition = condition

Sources/_MatchingEngine/Regex/AST/Group.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
extension AST {
1313
public struct Group: Hashable {
1414
public let kind: Located<Kind>
15-
public let child: AST
15+
public let child: AST.Node
1616

1717
public let location: SourceLocation
1818

1919
public init(
20-
_ kind: Located<Kind>, _ child: AST, _ r: SourceLocation
20+
_ kind: Located<Kind>, _ child: AST.Node, _ r: SourceLocation
2121
) {
2222
self.kind = kind
2323
self.child = child

Sources/_MatchingEngine/Regex/AST/Quantification.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ extension AST {
1414
public let amount: Located<Amount>
1515
public let kind: Located<Kind>
1616

17-
public let child: AST
17+
public let child: AST.Node
1818
public let location: SourceLocation
1919

2020
public init(
2121
_ amount: Located<Amount>,
2222
_ kind: Located<Kind>,
23-
_ child: AST,
23+
_ child: AST.Node,
2424
_ r: SourceLocation
2525
) {
2626
self.amount = amount

Sources/_MatchingEngine/Regex/Parse/CaptureStructure.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public enum CaptureStructure: Equatable {
2525
}
2626
}
2727

28-
extension AST {
28+
extension AST.Node {
2929
public var captureStructure: CaptureStructure {
3030
// Note: This implementation could be more optimized.
3131
switch self {
@@ -68,7 +68,7 @@ extension AST {
6868
var captures = CaptureStructure.empty
6969
switch c.condition.kind {
7070
case .group(let g):
71-
captures = captures + AST.group(g).captureStructure
71+
captures = captures + AST.Node.group(g).captureStructure
7272
default:
7373
break
7474
}

Sources/_MatchingEngine/Regex/Parse/Parse.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ extension Parser {
127127
}
128128
fatalError("Unhandled termination condition")
129129
}
130-
return ast
130+
return .init(ast)
131131
}
132132

133133
/// Parse a regular expression node. This should be used instead of `parse()`
@@ -136,7 +136,7 @@ extension Parser {
136136
/// RegexNode -> '' | Alternation
137137
/// Alternation -> Concatenation ('|' Concatenation)*
138138
///
139-
mutating func parseNode() throws -> AST {
139+
mutating func parseNode() throws -> AST.Node {
140140
let _start = source.currentPosition
141141

142142
if source.isEmpty { return .empty(.init(loc(_start))) }
@@ -163,8 +163,8 @@ extension Parser {
163163
/// ConcatComponent -> Trivia | Quote | Quantification
164164
/// Quantification -> QuantOperand Quantifier?
165165
///
166-
mutating func parseConcatenation() throws -> AST {
167-
var result = Array<AST>()
166+
mutating func parseConcatenation() throws -> AST.Node {
167+
var result = [AST.Node]()
168168
let _start = source.currentPosition
169169

170170
while true {
@@ -219,9 +219,9 @@ extension Parser {
219219
/// Perform a recursive parse for the branches of a conditional.
220220
mutating func parseConditionalBranches(
221221
start: Source.Position, _ cond: AST.Conditional.Condition
222-
) throws -> AST {
222+
) throws -> AST.Node {
223223
let child = try parseNode()
224-
let trueBranch: AST, falseBranch: AST, pipe: SourceLocation?
224+
let trueBranch: AST.Node, falseBranch: AST.Node, pipe: SourceLocation?
225225
switch child {
226226
case .alternation(let a):
227227
// If we have an alternation child, we only accept 2 branches.
@@ -316,7 +316,7 @@ extension Parser {
316316
/// Conditional -> ConditionalStart Concatenation ('|' Concatenation)? ')'
317317
/// ConditionalStart -> KnownConditionalStart | GroupConditionalStart
318318
///
319-
mutating func parseQuantifierOperand() throws -> AST? {
319+
mutating func parseQuantifierOperand() throws -> AST.Node? {
320320
assert(!source.isEmpty)
321321

322322
let _start = source.currentPosition

Sources/_MatchingEngine/Regex/Printing/DumpAST.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ extension _ASTPrintable {
2626
public var description: String { _print() }
2727
public var debugDescription: String { _dump() }
2828

29-
var _children: [AST]? {
29+
var _children: [AST.Node]? {
3030
if let children = (self as? _ASTParent)?.children {
3131
return children
3232
}
33-
if let children = (self as? AST)?.children {
33+
if let children = (self as? AST.Node)?.children {
3434
return children
3535
}
3636
return nil

Sources/_MatchingEngine/Regex/Printing/PrintAsCanonical.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,38 @@ extension AST {
2626
}
2727
}
2828

29+
extension AST.Node {
30+
/// Render using Swift's preferred regex literal syntax
31+
public func renderAsCanonical(
32+
showDelimiters delimiters: Bool = false,
33+
terminateLine: Bool = false
34+
) -> String {
35+
var printer = PrettyPrinter()
36+
printer.printAsCanonical(
37+
self,
38+
delimiters: delimiters,
39+
terminateLine: terminateLine)
40+
return printer.finish()
41+
}
42+
}
43+
2944
extension PrettyPrinter {
3045
/// Will output `ast` in canonical form, taking care to
3146
/// also indent and terminate the line (updating internal state)
3247
mutating func printAsCanonical(
3348
_ ast: AST,
3449
delimiters: Bool = false,
3550
terminateLine terminate: Bool = true
51+
) {
52+
printAsCanonical(ast.root, delimiters: delimiters, terminateLine: terminate)
53+
}
54+
55+
/// Will output `ast` in canonical form, taking care to
56+
/// also indent and terminate the line (updating internal state)
57+
mutating func printAsCanonical(
58+
_ ast: AST.Node,
59+
delimiters: Bool = false,
60+
terminateLine terminate: Bool = true
3661
) {
3762
indent()
3863
if delimiters { output("'/") }
@@ -45,7 +70,7 @@ extension PrettyPrinter {
4570

4671
/// Output the `ast` in canonical form, does not indent, terminate,
4772
/// or affect internal state
48-
mutating func outputAsCanonical(_ ast: AST) {
73+
mutating func outputAsCanonical(_ ast: AST.Node) {
4974
switch ast {
5075
case let .alternation(a):
5176
for idx in a.children.indices {

Sources/_MatchingEngine/Regex/Printing/PrintAsPattern.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extension AST {
3131

3232
extension PrettyPrinter {
3333
/// If pattern printing should back off, prints the regex literal and returns true
34-
mutating func patternBackoff(_ ast: AST) -> Bool {
34+
mutating func patternBackoff(_ ast: AST.Node) -> Bool {
3535
if let max = maxTopDownLevels, depth >= max {
3636
return true
3737
}
@@ -42,6 +42,10 @@ extension PrettyPrinter {
4242
}
4343

4444
mutating func printAsPattern(_ ast: AST) {
45+
printAsPattern(ast.root)
46+
}
47+
48+
mutating func printAsPattern(_ ast: AST.Node) {
4549
if patternBackoff(ast) {
4650
printAsCanonical(ast, delimiters: true)
4751
return
@@ -345,7 +349,7 @@ extension AST.Quantification.Kind {
345349
}
346350
}
347351

348-
extension AST {
352+
extension AST.Node {
349353
var height: Int {
350354
// FIXME: Is this right for custom char classes?
351355
// How do we count set operations?

Sources/_MatchingEngine/Regex/Printing/RenderRanges.swift

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,29 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
// Useful for testing, debugging, etc.
13-
extension AST {
14-
func _postOrder() -> Array<AST> {
15-
var nodes = Array<AST>()
13+
extension AST.Node {
14+
func _postOrder() -> Array<AST.Node> {
15+
var nodes = Array<AST.Node>()
1616
_postOrder(into: &nodes)
1717
return nodes
1818
}
19-
func _postOrder(into array: inout Array<AST>) {
19+
func _postOrder(into array: inout Array<AST.Node>) {
2020
children?.forEach { $0._postOrder(into: &array) }
2121
array.append(self)
2222
}
2323

24+
// Produce a textually "rendered" range
25+
//
26+
// NOTE: `input` must be the string from which a
27+
// source range was derived.
28+
func _renderRange(
29+
count: Int, into output: inout String
30+
) {
31+
guard count > 0 else { return }
32+
let repl = String(repeating: "-", count: count-1) + "^"
33+
output.replaceSubrange(location.range, with: repl)
34+
}
35+
2436
// We render from top-to-bottom, coalescing siblings
2537
public func _render(in input: String) -> [String] {
2638
let base = String(repeating: " ", count: input.count)
@@ -46,16 +58,10 @@ extension AST {
4658

4759
return lines.first!.all(\.isWhitespace) ? [] : lines
4860
}
49-
50-
// Produce a textually "rendered" rane
51-
//
52-
// NOTE: `input` must be the string from which a
53-
// source range was derived.
54-
func _renderRange(
55-
count: Int, into output: inout String
56-
) {
57-
guard count > 0 else { return }
58-
let repl = String(repeating: "-", count: count-1) + "^"
59-
output.replaceSubrange(location.range, with: repl)
61+
}
62+
extension AST {
63+
// We render from top-to-bottom, coalescing siblings
64+
public func _render(in input: String) -> [String] {
65+
root._render(in: input)
6066
}
6167
}

0 commit comments

Comments
 (0)