Skip to content

Commit 7074cfb

Browse files
committed
Elaborate on comma case
1 parent c7d556c commit 7074cfb

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

Documentation/Evolution/DelimiterSyntax.md

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ The obvious parsing ambiguity with `/.../` delimiters is with comment syntaxes.
9090

9191
#### Regex limitations
9292

93-
In order to help avoid parsing ambiguities, a regex literal will not be parsed if it starts with a space, tab, or `)` character. Though the latter is already invalid regex syntax.
93+
In order to help avoid further parsing ambiguities, a regex literal will not be parsed if it starts with a space, tab, or `)` character. Though the latter is already invalid regex syntax.
9494

9595
<details><summary>Rationale</summary>
9696

97-
This is due to 2 main ambiguities. The first of which arises when a `/.../` regex literal is used to start a new line. This is particularly problematic for result builders, where we expect it to be frequently used, for example:
97+
This is due to 2 main ambiguities. The first of which arises when a `/.../` regex literal starts a new line. This is particularly problematic for result builders, where we expect it to be frequently used, for example:
9898

9999
```swift
100100
Builder {
@@ -116,16 +116,14 @@ Builder {
116116
}
117117
```
118118

119-
The second ambiguity arises with Swift's ability to pass an unapplied operator reference as an argument to a function, for example:
119+
The second ambiguity arises with Swift's ability to pass an unapplied operator reference as an argument to a function for example:
120120

121121
```swift
122122
let arr: [Double] = [2, 3, 4]
123123
let x = arr.reduce(1, /) / 5
124124
```
125125

126-
The `/` in the call to `reduce` is in a valid expression context, and as such could be passed as a regular expression literal. To help mitigate this ambiguity, a regex literal will not be parsed if the first character is `)`. Note this would not be valid regex syntax anyway.
127-
128-
This is also applicable to unapplied operator references in parentheses and tuples.
126+
The `/` in the call to `reduce` is in a valid expression context, and as such could be parsed as a regex literal. This is also applicable to operators in tuples and parentheses. To help mitigate this ambiguity, a regex literal will not be parsed if the first character is `)`. This should have minimal impact, as this would not be valid regex syntax anyway.
129127

130128
It should be noted that this only mitigates the issue, as another ambiguity arises if the next character is a comma:
131129

@@ -143,7 +141,7 @@ However we feel that starting a regex with a comma is likely to be a common case
143141
In addition to ambiguities listed above, there are also some parsing ambiguities that would require the following language changes:
144142

145143
- Deprecation of prefix operators containing the `/` character.
146-
- Potentially parsing `/,` as the start of a regex literal rather than an unapplied operator in an argument list e.g `fn(/, 5) + fn(/, 3)`.
144+
- Potentially parsing `/,` as the start of a regex literal rather than an unapplied operator in an argument list. For example, `fn(/, /)` becomes a regex literal rather than 2 unapplied operator arguments. **TODO: Or do we want to ban it as the starting character? Seems like a common regex case**
147145

148146
<details><summary>Rationale</summary>
149147

@@ -167,23 +165,32 @@ let x = !/y / .foo()
167165
```
168166

169167
Otherwise it would be interpreted as the prefix operator `!/` by default, and require parens `!(/y /)` for regex parsing.
168+
169+
##### Comma as the starting character of a regex literal
170170

171+
As stated previously, there is a parsing ambiguity with unapplied operators in argument lists, tuples, and parentheses. Some of these cases can be mitigated by not parsing a regex literal if the starting character is `)`. However it does not solve the issue when the next character is `,`, i.e `/` is used in an argument list before another argument.
171172

172-
173-
**TODO: More cases from slack discussion **
173+
For example:
174174

175175
```swift
176176
func foo(_ x: (Int, Int) -> Int, _ y: (Int, Int) -> Int) {}
177177
foo(/, /)
178178
```
179179

180-
`foo(/, "(") / 2` !!!
180+
This is currently parsed as 2 unapplied operator arguments. However, given the fact that a regex starting with a comma is not an uncommon case, this will become a regex literal.
181181

182+
The above case seems uncommon, however note this may also occur when the closing `/` appears outside of the argument list, e.g:
182183

183-
184-
##### Comma as the starting character of a regex literal
184+
```swift
185+
foo(/, 2) + foo(/, 3)
186+
```
187+
188+
This would also become a regex literal, i.e it would be parsed as the argument `/, 2) + foo(/`.
189+
190+
**TODO: More cases from slack discussion **
191+
192+
`foo(/, "(") / 2` !!!
185193

186-
**TODO: Or do we want to ban it as the starting character?**
187194

188195
</details>
189196

0 commit comments

Comments
 (0)