Skip to content

Commit 7cfbfef

Browse files
committed
Add #/.../# and re'...' delimiters
Replace the `'/.../'` and `'|...|'` delimiters with `#/.../#` and `#|...|#` respectively. Additionally, implement a `re'...'` delimiter.
1 parent 8ed3fca commit 7cfbfef

File tree

3 files changed

+38
-29
lines changed

3 files changed

+38
-29
lines changed

Sources/_MatchingEngine/Regex/Parse/Mocking.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
enum Delimiter: Hashable, CaseIterable {
1616
case traditional
1717
case experimental
18+
case reSingleQuote
1819

1920
var openingAndClosing: (opening: String, closing: String) {
2021
switch self {
21-
case .traditional: return ("'/", "/'")
22-
case .experimental: return ("'|", "|'")
22+
case .traditional: return ("#/", "/#")
23+
case .experimental: return ("#|", "|#")
24+
case .reSingleQuote: return ("re'", "'")
2325
}
2426
}
2527
var opening: String { openingAndClosing.opening }
@@ -28,8 +30,10 @@ enum Delimiter: Hashable, CaseIterable {
2830
/// The default set of syntax options that the delimiter indicates.
2931
var defaultSyntaxOptions: SyntaxOptions {
3032
switch self {
31-
case .traditional: return .traditional
32-
case .experimental: return .experimental
33+
case .traditional, .reSingleQuote:
34+
return .traditional
35+
case .experimental:
36+
return .experimental
3337
}
3438
}
3539
}

Tests/RegexTests/LexTests.swift

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,23 +102,26 @@ extension RegexTests {
102102

103103
func testCompilerInterface() {
104104
let testCases: [(String, (String, Delimiter)?)] = [
105-
("'/abc/'", ("abc", .traditional)),
106-
("'|abc|'", ("abc", .experimental)),
105+
("#/abc/#", ("abc", .traditional)),
106+
("#|abc|#", ("abc", .experimental)),
107107

108108
// TODO: Null characters are lexically valid, similar to string literals,
109109
// but we ought to warn the user about them.
110-
("'|ab\0c|'", ("ab\0c", .experimental)),
110+
("#|ab\0c|#", ("ab\0c", .experimental)),
111111
("'abc'", nil),
112-
("'/abc/def/'", ("abc/def", .traditional)),
113-
("'|abc|def|'", ("abc|def", .experimental)),
114-
("'/abc\\/'def/'", ("abc\\/'def", .traditional)),
115-
("'|abc\\|'def|'", ("abc\\|'def", .experimental)),
116-
("'/abc|'def/'", ("abc|'def", .traditional)),
117-
("'|abc/'def|'", ("abc/'def", .experimental)),
118-
("'/abc|'def/", nil),
119-
("'|abc/'def'", nil),
120-
("'/abc\n/'", nil),
121-
("'/abc\r/'", nil),
112+
("#/abc/def/#", ("abc/def", .traditional)),
113+
("#|abc|def|#", ("abc|def", .experimental)),
114+
("#/abc\\/#def/#", ("abc\\/#def", .traditional)),
115+
("#|abc\\|#def|#", ("abc\\|#def", .experimental)),
116+
("#/abc|#def/#", ("abc|#def", .traditional)),
117+
("#|abc/#def|#", ("abc/#def", .experimental)),
118+
("#/abc|#def/", nil),
119+
("#|abc/#def#", nil),
120+
("#/abc\n/#", nil),
121+
("#/abc\r/#", nil),
122+
123+
(#"re'abcre\''"#, (#"abcre\'"#, .reSingleQuote)),
124+
(#"re'\'"#, nil)
122125
]
123126

124127
for (input, expected) in testCases {

Tests/RegexTests/ParseTests.swift

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,31 +1436,33 @@ extension RegexTests {
14361436

14371437
// MARK: Parse with delimiters
14381438

1439-
parseWithDelimitersTest("'/a b/'", concat("a", " ", "b"))
1440-
parseWithDelimitersTest("'|a b|'", concat("a", "b"))
1439+
parseWithDelimitersTest("#/a b/#", concat("a", " ", "b"))
1440+
parseWithDelimitersTest("#|a b|#", concat("a", "b"))
14411441

1442-
parseWithDelimitersTest("'|[a b]|'", charClass("a", "b"))
1442+
parseWithDelimitersTest("#|[a b]|#", charClass("a", "b"))
14431443
parseWithDelimitersTest(
1444-
"'|(?-x)[a b]|'", changeMatchingOptions(
1444+
"#|(?-x)[a b]|#", changeMatchingOptions(
14451445
matchingOptions(removing: .extended), isIsolated: true,
14461446
charClass("a", " ", "b"))
14471447
)
1448-
parseWithDelimitersTest("'|[[a ] b]|'", charClass(charClass("a"), "b"))
1448+
parseWithDelimitersTest("#|[[a ] b]|#", charClass(charClass("a"), "b"))
14491449

14501450
// Non-semantic whitespace between quantifier characters for consistency
14511451
// with PCRE.
1452-
parseWithDelimitersTest("'|a * ?|'", zeroOrMore(.reluctant, of: "a"))
1452+
parseWithDelimitersTest("#|a * ?|#", zeroOrMore(.reluctant, of: "a"))
14531453

14541454
// End-of-line comments aren't enabled by default in experimental syntax.
1455-
parseWithDelimitersTest("'|#abc|'", concat("#", "a", "b", "c"))
1456-
parseWithDelimitersTest("'|(?x)#abc|'", changeMatchingOptions(
1455+
parseWithDelimitersTest("#|#abc|#", concat("#", "a", "b", "c"))
1456+
parseWithDelimitersTest("#|(?x)#abc|#", changeMatchingOptions(
14571457
matchingOptions(adding: .extended), isIsolated: true,
14581458
empty())
14591459
)
14601460

1461-
parseWithDelimitersTest("'|||'", alt(empty(), empty()))
1462-
parseWithDelimitersTest("'||||'", alt(empty(), empty(), empty()))
1463-
parseWithDelimitersTest("'|a||'", alt("a", empty()))
1461+
parseWithDelimitersTest("#|||#", alt(empty(), empty()))
1462+
parseWithDelimitersTest("#||||#", alt(empty(), empty(), empty()))
1463+
parseWithDelimitersTest("#|a||#", alt("a", empty()))
1464+
1465+
parseWithDelimitersTest("re'x*'", zeroOrMore(of: "x"))
14641466

14651467
// MARK: Parse not-equal
14661468

@@ -1878,6 +1880,6 @@ extension RegexTests {
18781880

18791881
func testlibswiftDiagnostics() {
18801882
libswiftDiagnosticMessageTest(
1881-
"'/[x*/'", "cannot parse regular expression: expected ']'")
1883+
"#/[x*/#", "cannot parse regular expression: expected ']'")
18821884
}
18831885
}

0 commit comments

Comments
 (0)