diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/antlr4/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/antlr4/Swift.g4
index 01ee4ad84c..c71b5fbda7 100644
--- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/antlr4/Swift.g4
+++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/antlr4/Swift.g4
@@ -1018,7 +1018,7 @@ ImplicitParameterName : '$' DecimalLiteral ; // TODO: don't allow '_' here
// GRAMMAR OF A LITERAL
booleanLiteral: BooleanLiteral ;
-literal : numericLiteral | MultiStringLiteral | SingleStringLiteral | BooleanLiteral | NilLiteral ;
+literal : numericLiteral | MultiStringLiteral | DashedSingleStringLiteral | SingleStringLiteral | BooleanLiteral | NilLiteral ;
// GRAMMAR OF AN INTEGER LITERAL
@@ -1078,6 +1078,13 @@ fragment MultiQuotedTextItem : MultiInterpolatedString
;
fragment MultiInterpolatedString: '\\(' (MultiQuotedTextItem | SingleStringLiteral)* ')';
+DashedSingleStringLiteral : '#"' DashedMultiQuotedText? '"#' ;
+fragment DashedMultiQuotedText : DashedMultiQuotedTextItem+ ;
+fragment DashedMultiQuotedTextItem : EscapedCharacter | DashedMultiInterpolatedString
+ | ~[\\\u000A\u000D]
+ ;
+fragment DashedMultiInterpolatedString: '\\#(' (DashedMultiQuotedTextItem | DashedSingleStringLiteral)* ')';
+
// StringLiteral : '"' QuotedText? '"' ;
SingleStringLiteral : '"' QuotedText? '"' ;
fragment SingleDoubleQuote : '"' | ~["] ;
diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.swift
index 6e77f1dd29..cf326c21c7 100644
--- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.swift
+++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.swift
@@ -38,3 +38,11 @@ var x = 2
print(x[keyPath: id]) // prints 2
x[keyPath: id] = 3
print(x[keyPath: id]) // prints 3
+
+// https://www.swiftbysundell.com/articles/string-literals-in-swift/
+let rawString = #"Press "Continue" to close this dialog."#
+extension URL {
+ func html(withTitle title: String) -> String {
+ return #"\#(title)"#
+ }
+}
diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt
index 5eaa13610c..0a89406a83 100644
--- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt
+++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt
@@ -197,4 +197,37 @@ L40
[id] 18 19
[\]] 20 20
[)] 21 21
+L43
+ [let] 1 3
+ [rawString] 5 13
+ [=] 15 15
+ [#"Press "Continue" to close this d[ 17 58
+L44
+ [extension] 1 9
+ [URL] 11 13
+ [{] 15 15
+L45
+ [func] 5 8
+ [html] 10 13
+ [(] 14 14
+ [withTitle] 15 23
+ [title] 25 29
+ [:] 30 30
+ [String] 32 37
+ [)] 38 38
+ [->] 40 41
+ [String] 43 48
+ [{] 50 50
+L46
+ [return] 9 14
+ [#"\\[ 16 61
+L47
+ [}] 5 5
+L48
+ [}] 1 1
+L49
+ [let] 1 3
+ [regex] 5 9
+ [=] 11 11
+ [#"w+"#] 13 18
EOF