Skip to content

Commit 6803dbf

Browse files
authored
Merge pull request #413 from Azoy/oops-i-did-it-agan
Handle atoms as things to be wrapped in One
2 parents e6a4032 + 06e6e02 commit 6803dbf

File tree

2 files changed

+88
-43
lines changed

2 files changed

+88
-43
lines changed

Diff for: Sources/_StringProcessing/PrintAsPattern.swift

+79-31
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ extension PrettyPrinter {
127127
print("/* TODO: conditional */")
128128

129129
case let .quantification(amount, kind, child):
130-
let amount = amount.ast._patternBase
130+
let amountStr = amount.ast._patternBase
131131
var kind = kind.ast?._patternBase ?? ""
132132

133133
// If we've updated our quantification behavior, then use that. This
@@ -137,10 +137,10 @@ extension PrettyPrinter {
137137
kind = quantificationBehavior._patternBase
138138
}
139139

140-
var blockName = "\(amount)(\(kind))"
140+
var blockName = "\(amountStr)(\(kind))"
141141

142142
if kind == ".eager" {
143-
blockName = "\(amount)"
143+
blockName = "\(amountStr)"
144144
}
145145

146146
// Special case single child character classes for repetition nodes.
@@ -152,6 +152,20 @@ extension PrettyPrinter {
152152
// One(.digit)
153153
// }
154154
//
155+
func printAtom(_ pattern: String) {
156+
indent()
157+
158+
if kind != ".eager" {
159+
blockName.removeLast()
160+
output("\(blockName), ")
161+
} else {
162+
output("\(blockName)(")
163+
}
164+
165+
output("\(pattern))")
166+
terminateLine()
167+
}
168+
155169
func printSimpleCCC(
156170
_ ccc: DSLTree.CustomCharacterClass
157171
) {
@@ -169,23 +183,42 @@ extension PrettyPrinter {
169183
terminateLine()
170184
}
171185

172-
switch child {
173-
case let .customCharacterClass(ccc):
174-
if ccc.isSimplePrint {
175-
printSimpleCCC(ccc)
176-
return
177-
}
178-
179-
break
180-
case let .convertedRegexLiteral(.customCharacterClass(ccc), _):
181-
if ccc.isSimplePrint {
182-
printSimpleCCC(ccc)
183-
return
186+
// We can only do this for Optionally, ZeroOrMore, and OneOrMore. Cannot
187+
// do it right now for Repeat.
188+
if amount.ast.supportsInlineComponent {
189+
switch child {
190+
case let .atom(a):
191+
if let pattern = a._patternBase(&self), pattern.canBeWrapped {
192+
printAtom(pattern.0)
193+
return
194+
}
195+
196+
break
197+
case let .customCharacterClass(ccc):
198+
if ccc.isSimplePrint {
199+
printSimpleCCC(ccc)
200+
return
201+
}
202+
203+
break
204+
205+
case let .convertedRegexLiteral(.atom(a), _):
206+
if let pattern = a._patternBase(&self), pattern.canBeWrapped {
207+
printAtom(pattern.0)
208+
return
209+
}
210+
211+
break
212+
case let .convertedRegexLiteral(.customCharacterClass(ccc), _):
213+
if ccc.isSimplePrint {
214+
printSimpleCCC(ccc)
215+
return
216+
}
217+
218+
break
219+
default:
220+
break
184221
}
185-
186-
break
187-
default:
188-
break
189222
}
190223

191224
printBlock(blockName) { printer in
@@ -199,7 +232,11 @@ extension PrettyPrinter {
199232
}
200233

201234
if let pattern = a._patternBase(&self) {
202-
print(pattern)
235+
if pattern.canBeWrapped {
236+
print("One(\(pattern.0))")
237+
} else {
238+
print(pattern.0)
239+
}
203240
}
204241

205242
case .trivia:
@@ -391,9 +428,9 @@ extension PrettyPrinter {
391428
if let lhs = lhs._patternBase(&self), let rhs = rhs._patternBase(&self) {
392429
indent()
393430
output("(")
394-
output(lhs)
431+
output(lhs.0)
395432
output("...")
396-
output(rhs)
433+
output(rhs.0)
397434
output(")")
398435
}
399436

@@ -939,6 +976,15 @@ extension AST.Quantification.Amount {
939976
case let .range(n, m): return "Repeat(\(n.value)...\(m.value))"
940977
}
941978
}
979+
980+
var supportsInlineComponent: Bool {
981+
switch self {
982+
case .zeroOrMore: return true
983+
case .oneOrMore: return true
984+
case .zeroOrOne: return true
985+
default: return false
986+
}
987+
}
942988
}
943989

944990
extension AST.Quantification.Kind {
@@ -1033,33 +1079,35 @@ extension DSLTree.CustomCharacterClass {
10331079
}
10341080

10351081
extension DSLTree.Atom {
1036-
func _patternBase(_ printer: inout PrettyPrinter) -> String? {
1082+
func _patternBase(
1083+
_ printer: inout PrettyPrinter
1084+
) -> (String, canBeWrapped: Bool)? {
10371085
switch self {
10381086
case .any:
1039-
return ".any"
1087+
return (".any", true)
10401088

10411089
case let .char(c):
1042-
return String(c)._quoted
1090+
return (String(c)._quoted, false)
10431091

10441092
case let .scalar(s):
10451093
let hex = String(s.value, radix: 16, uppercase: true)
1046-
return "\\u{\(hex)}"._quoted
1094+
return ("\\u{\(hex)}"._quoted, false)
10471095

10481096
case let .unconverted(a):
10491097
if a.ast.isUnprintableAtom {
1050-
return "#/\(a.ast._regexBase)/#"
1098+
return ("#/\(a.ast._regexBase)/#", false)
10511099
} else {
1052-
return a.ast._dslBase.0
1100+
return a.ast._dslBase
10531101
}
10541102

10551103
case .assertion(let a):
1056-
return a.ast._patternBase
1104+
return (a.ast._patternBase, false)
10571105

10581106
case .backreference(_):
1059-
return "/* TOOD: backreferences */"
1107+
return ("/* TOOD: backreferences */", false)
10601108

10611109
case .symbolicReference:
1062-
return "/* TOOD: symbolic references */"
1110+
return ("/* TOOD: symbolic references */", false)
10631111

10641112
case .changeMatchingOptions(let matchingOptions):
10651113
for add in matchingOptions.ast.adding {

Diff for: Tests/RegexTests/RenderDSLTests.swift

+9-12
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,17 @@ extension RenderDSLTests {
5656

5757
try testConversion(#"\d+"#, """
5858
Regex {
59-
OneOrMore {
60-
.digit
61-
}
59+
OneOrMore(.digit)
60+
}
61+
""")
62+
63+
try testConversion(#":\d:"#, """
64+
Regex {
65+
":"
66+
One(.digit)
67+
":"
6268
}
6369
""")
64-
try XCTExpectFailure("Invalid leading dot syntax in non-initial position") {
65-
try testConversion(#":\d:"#, """
66-
Regex {
67-
":"
68-
CharacterClass.digit
69-
":"
70-
}
71-
""")
72-
}
7370
}
7471

7572
func testOptions() throws {

0 commit comments

Comments
 (0)