Skip to content

Commit 87ead75

Browse files
RexJaeschkeBillWagner
authored andcommitted
Support raw string literals
1 parent 044cf48 commit 87ead75

1 file changed

Lines changed: 78 additions & 12 deletions

File tree

standard/expressions.md

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,14 +1406,14 @@ $"val = {{{val,4:X}}}; 2 * val = {2 * val}."
14061406

14071407
This contains the interpolated string expression segments `"val = {"`, `"}; 2 * val = "`, and `"."`, the first of which factors in the presence of the open/close brace escape sequences described in the grammar below. The quoted text also contains the interpolations `"{val,4:X}"` and `"{2 * val}"`.
14081408

1409-
Interpolated string expressions have two forms; regular (*interpolated_regular_string_expression*)
1410-
and verbatim (*interpolated_verbatim_string_expression*); which are lexically similar to, but differ semantically from, the two forms of string
1411-
literals ([§6.4.5.6](lexical-structure.md#6456-string-literals)).
1409+
An *interpolated_string_expression* has one of the following forms; regular (*interpolated_regular_string_expression*),
1410+
verbatim (*interpolated_verbatim_string_expression*), and raw (*interpolated_raw_string_expression*); which are lexically similar to, but differ semantically from, the corresponding forms of string literals ([§6.4.5.6](lexical-structure.md#6456-string-literals)).
14121411

14131412
```ANTLR
14141413
interpolated_string_expression
14151414
: interpolated_regular_string_expression
14161415
| interpolated_verbatim_string_expression
1416+
| interpolated_raw_string_expression
14171417
;
14181418
14191419
// interpolated regular string expressions
@@ -1518,16 +1518,79 @@ fragment Open_Brace_Escape_Sequence
15181518
fragment Close_Brace_Escape_Sequence
15191519
: '}}'
15201520
;
1521+
1522+
// interpolated raw string expressions
1523+
1524+
interpolated_raw_string_expression
1525+
: single_line_interpolated_raw_string_expression
1526+
| multi_line_interpolated_raw_string_expression
1527+
;
1528+
1529+
single_line_interpolated_raw_string_expression
1530+
: Interpolated_Raw_String_Start Interpolated_Raw_String_Mid
1531+
Interpolated_Raw_String_End
1532+
;
1533+
1534+
Interpolated_Raw_String_Prefix
1535+
: '$'+
1536+
;
1537+
1538+
Interpolated_Raw_String_Start
1539+
: Interpolated_Raw_String_Prefix Raw_String_Literal_Delimiter
1540+
;
1541+
1542+
// the following two lexical rules are context sensitive, see details below
1543+
1544+
Interpolated_Raw_String_Mid
1545+
: (Raw_String_Literal_Content | raw_interpolation)+
1546+
;
1547+
1548+
Interpolated_Raw_String_End
1549+
: Raw_String_Literal_Delimiter
1550+
;
1551+
1552+
raw_interpolation
1553+
: raw_interpolation_start expression
1554+
(',' interpolation_minimum_width)? Raw_Interpolation_Format?
1555+
raw_interpolation_end
1556+
;
1557+
1558+
raw_interpolation_start
1559+
: '{'+
1560+
;
1561+
1562+
raw_interpolation_end
1563+
: '}'+
1564+
;
1565+
1566+
// the following lexical rule is context sensitive, see details below
1567+
1568+
Raw_Interpolation_Format
1569+
: ':' Interpolated_Raw_String_Character+
1570+
;
1571+
1572+
fragment Interpolated_Raw_String_Character
1573+
// Any character except " (U+0022), \\ (U+005C),
1574+
// { (U+007B), } (U+007D), and New_Line_Character.
1575+
: ~["\\{}\u000D\u000A\u0085\u2028\u2029]
1576+
;
1577+
1578+
multi_line_interpolated_raw_string_expression
1579+
: Interpolated_Raw_String_Start Whitespace* New_Line
1580+
(Interpolated_Raw_String_Mid | New_Line)* New_Line
1581+
Whitespace* Interpolated_Raw_String_End
1582+
;
15211583
```
15221584

1523-
Six of the lexical rules defined above are *context sensitive* as follows:
1585+
A number of the lexical rules defined above are *context sensitive* as follows:
15241586

15251587
| **Rule** | **Contextual Requirements** |
15261588
| :------- | :-------------------------- |
15271589
| *Interpolated_Regular_String_Mid* | Only recognised after an *Interpolated_Regular_String_Start*, between any following interpolations, and before the corresponding *Interpolated_Regular_String_End*. |
15281590
| *Regular_Interpolation_Format* | Only recognised within a *regular_interpolation* and when the starting colon (:) is not nested within any kind of bracket (parentheses/braces/square). |
15291591
| *Interpolated_Regular_String_End* | Only recognised after an *Interpolated_Regular_String_Start* and only if any intervening tokens are either *Interpolated_Regular_String_Mid*s or tokens that can be part of *regular_interpolation*s, including tokens for any *interpolated_regular_string_expression*s contained within such interpolations. |
1530-
| *Interpolated_Verbatim_String_Mid* *Verbatim_Interpolation_Format* *Interpolated_Verbatim_String_End* | Recognition of these three rules follows that of the corresponding rules above with each mentioned *regular* grammar rule replaced by the corresponding *verbatim* one. |
1592+
| *Interpolated_Verbatim_String_Mid* *Verbatim_Interpolation_Format* *Interpolated_Verbatim_String_End* | Recognition of these three rules follows that of the corresponding first three rules above with each mentioned *regular* grammar rule replaced by the corresponding *verbatim* one. |
1593+
| *Interpolated_Raw_String_Mid* *Raw_Interpolation_Format* *Interpolated_Raw_String_End* | Recognition of these three rules follows that of the corresponding first three rules above with each mentioned *regular* grammar rule replaced by the corresponding *raw* one. |
15311594

15321595
> *Note*: The above rules are context sensitive as their definitions overlap with those of
15331596
other tokens in the language. *end note*
@@ -1564,7 +1627,7 @@ M(str2); // invokes M(SomeInterpolatedStringHandler)
15641627

15651628
The remainder of this subclause deals with the default interpolated string handler behavior only. The declaration and use of custom interpolated string handlers is described in [§23.5.9.1](attributes.md#23591-custom-interpolated-string-expression-handlers).
15661629

1567-
The meaning of an interpolation, both *regular_interpolation* and *verbatim_interpolation*, is to format the value of the *expression* as a `string` either according to the format specified by the *Regular_Interpolation_Format* or *Verbatim_Interpolation_Format*, or according to a default format for the type of *expression*. The formatted string is then modified by the *interpolation_minimum_width*, if any, to produce the final `string` to be interpolated into the *interpolated_string_expression*.
1630+
The meaning of an interpolation (*regular_interpolation*, *verbatim_interpolation*, and *raw_interpolation*) is to format the value of the *expression* as a `string` either according to the format specified by the *Regular_Interpolation_Format*, *Verbatim_Interpolation_Format*, or *Raw_Interpolation_Format*, or according to a default format for the type of *expression*. The formatted string is then modified by the *interpolation_minimum_width*, if any, to produce the final `string` to be interpolated into the *interpolated_string_expression*.
15681631

15691632
In an *interpolation_minimum_width* the *constant_expression* shall have an implicit conversion to `int`. Let the *field width* be the absolute value of this *constant_expression* and the *alignment* be the sign (positive or negative) of the value of this *constant_expression*:
15701633

@@ -1577,17 +1640,17 @@ The interpolated string expression is treated as a *format string literal* with
15771640

15781641
The format string literal is constructed as follows, where `N` is the number of interpolations in the *interpolated_string_expression*. The format string literal consists of, in order:
15791642

1580-
- The characters of the *Interpolated_Regular_String_Start* or *Interpolated_Verbatim_String_Start*
1581-
- The characters of the *Interpolated_Regular_String_Mid* or *Interpolated_Verbatim_String_Mid*, if any
1643+
- The characters of the *Interpolated_Regular_String_Start*, *Interpolated_Verbatim_String_Start*, or *Interpolated_Raw_String_Start*
1644+
- The characters of the *Interpolated_Regular_String_Mid*, *Interpolated_Verbatim_String_Mid*, or *Interpolated_Raw_String_Mid*, if any
15821645
- Then if `N ≥ 1` for each number `I` from `0` to `N-1`:
15831646
- A placeholder specification:
15841647
- A left brace (`{`) character
15851648
- The decimal representation of `I`
1586-
- Then, if the corresponding *regular_interpolation* or *verbatim_interpolation* has a *interpolation_minimum_width*, a comma (`,`) followed by the decimal representation of the value of the *constant_expression*
1587-
- The characters of the *Regular_Interpolation_Format* or *Verbatim_Interpolation_Format*, if any, of the corresponding *regular_interpolation* or *verbatim_interpolation*
1649+
- Then, if the corresponding *regular_interpolation*, *verbatim_interpolation*, or *raw_interpolation* has a *interpolation_minimum_width*, a comma (`,`) followed by the decimal representation of the value of the *constant_expression*
1650+
- The characters of the *Regular_Interpolation_Format*, *Verbatim_Interpolation_Format*, or *Raw_Interpolation_Format*, if any, of the corresponding *regular_interpolation*, *verbatim_interpolation*, or *raw_interpolation*
15881651
- A right brace (`}`) character
1589-
- The characters of the *Interpolated_Regular_String_Mid* or *Interpolated_Verbatim_String_Mid* immediately following the corresponding interpolation, if any
1590-
- Finally the characters of the *Interpolated_Regular_String_End* or *Interpolated_Verbatim_String_End*.
1652+
- The characters of the *Interpolated_Regular_String_Mid*, *Interpolated_Verbatim_String_Mid*, or *Interpolated_Raw_String_Mid* immediately following the corresponding interpolation, if any
1653+
- Finally the characters of the *Interpolated_Regular_String_End*, *Interpolated_Verbatim_String_End*, or *Interpolated_Raw_String_End*.
15911654

15921655
The subsequent arguments are the *expression*s from the interpolations, if any, in order.
15931656

@@ -1625,6 +1688,9 @@ Then:
16251688
| `$"{text + '?'} {number % 3}"` | `string.Format("{0} {1}", text + '?', number % 3)` | `"red? 2"` |
16261689
| `$"{text + $"[{number}]"}"` | `string.Format("{0}", text + string.Format("[{0}]", number))` | `"red[14]"` |
16271690
| `$"{(number==0?"Zero":"Non-zero")}"` | `string.Format("{0}", (number==0?"Zero":"Non-zero"))` | `"Non-zero"` |
1691+
| `$$""""{number}""""` | `string.Format("{{number}}")` | `"{number}"` |
1692+
| `$$"""{{number}}"""` | `string.Format("{0}", number)` | `"14"` |
1693+
| `$$"""""{{{number}}}"""""` | `string.Format("{{{0}}}", number)` | `"{14}"` |
16281694

16291695
*end example*
16301696

0 commit comments

Comments
 (0)