Skip to content

Commit aebb6f0

Browse files
RexJaeschkejskeet
authored andcommitted
Update lexical-structure.md
1 parent dd3f7ea commit aebb6f0

File tree

1 file changed

+97
-8
lines changed

1 file changed

+97
-8
lines changed

standard/lexical-structure.md

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -616,34 +616,87 @@ The type of a *boolean_literal* is `bool`.
616616

617617
#### 6.4.5.3 Integer literals
618618

619-
Integer literals are used to write values of types `int`, `uint`, `long`, and `ulong`. Integer literals have two possible forms: decimal and hexadecimal.
619+
Integer literals are used to write values of types `int`, `uint`, `long`, and `ulong`. Integer literals have three possible forms: decimal and, hexadecimal, and binary.
620620

621621
```ANTLR
622622
Integer_Literal
623623
: Decimal_Integer_Literal
624624
| Hexadecimal_Integer_Literal
625+
| Binary_Integer_Literal
625626
;
626627
627628
fragment Decimal_Integer_Literal
628-
: Decimal_Digit+ Integer_Type_Suffix?
629+
: Decimal_Digits Integer_Type_Suffix?
630+
;
631+
632+
fragment Decimal_Digits
633+
: Decimal_Digit
634+
| Decimal_Digit Decimal_Digits_And_Underscores? Decimal_Digit
629635
;
630636
631637
fragment Decimal_Digit
632638
: '0'..'9'
633639
;
634640
641+
fragment Decimal_Digits_And_Underscores
642+
: Decimal_Digits_And_Underscore+
643+
;
644+
645+
fragment Decimal_Digits_And_Underscore
646+
: Decimal_Digit
647+
| '_'
648+
;
649+
635650
fragment Integer_Type_Suffix
636651
: 'U' | 'u' | 'L' | 'l' |
637652
'UL' | 'Ul' | 'uL' | 'ul' | 'LU' | 'Lu' | 'lU' | 'lu'
638653
;
639654
640655
fragment Hexadecimal_Integer_Literal
641-
: ('0x' | '0X') Hex_Digit+ Integer_Type_Suffix?
656+
: ('0x' | '0X') Hex_Digits Integer_Type_Suffix?
657+
;
658+
659+
fragment Hex_Digits
660+
: '_'* Hex_Digit
661+
| '_'* Hex_Digit Hex_Digits_And_Underscores? Hex_Digit
642662
;
643663
644664
fragment Hex_Digit
645665
: '0'..'9' | 'A'..'F' | 'a'..'f'
646666
;
667+
668+
fragment Hex_Digits_And_Underscores
669+
: Hex_Digits_And_Underscore+
670+
;
671+
672+
fragment Hex_Digits_And_Underscore
673+
: Hex_Digit
674+
| '_'
675+
;
676+
677+
fragment Binary_Integer_Literal
678+
: '0b' Binary_Digits Integer_Type_Suffix?
679+
| '0B' Binary_Digits Integer_Type_Suffix?
680+
;
681+
682+
fragment Binary_Digits
683+
: '_'* Binary_Digit
684+
| '_'* Binary_Digit Binary_Digits_And_Underscores? Binary_Digit
685+
;
686+
687+
fragment Binary_Digit
688+
: '0'
689+
| '1'
690+
;
691+
692+
fragment Binary_Digits_And_Underscores
693+
: Binary_Digits_And_Underscore+
694+
;
695+
696+
fragment Binary_Digits_And_Underscore
697+
: Binary_Digit
698+
| '_'
699+
;
647700
```
648701

649702
The type of an integer literal is determined as follows:
@@ -662,20 +715,41 @@ To permit the smallest possible `int` and `long` values to be written as integer
662715
- When an *Integer_Literal* representing the value `2147483648` (2³¹) and no *Integer_Type_Suffix* appears as the token immediately following a unary minus operator token ([§11.8.3](expressions.md#1183-unary-minus-operator)), the result (of both tokens) is a constant of type int with the value `−2147483648` (−2³¹). In all other situations, such an *Integer_Literal* is of type `uint`.
663716
- When an *Integer_Literal* representing the value `9223372036854775808` (2⁶³) and no *Integer_Type_Suffix* or the *Integer_Type_Suffix* `L` or `l` appears as the token immediately following a unary minus operator token ([§11.8.3](expressions.md#1183-unary-minus-operator)), the result (of both tokens) is a constant of type `long` with the value `−9223372036854775808` (−2⁶³). In all other situations, such an *Integer_Literal* is of type `ulong`.
664717

718+
> *Example*:
719+
>
720+
> ```csharp
721+
> 123 // decimal, int
722+
> 10_543_765Lu // decimal, ulong
723+
> 1_2__3___4____5 // decimal, int
724+
>
725+
> 0xFf // hex, int
726+
> 0X1b_a0_44_fEL // hex, long
727+
> 0x1ade_3FE1_29AaUL // hex, ulong
728+
> 0x_abc // hex, int
729+
> 0xabc_ // invalid; no trailing _ allowed
730+
>
731+
> 0b101 // binary, int
732+
> 0B1001_1010u // binary, uint
733+
> 0b1111_1111_0000UL // binary, ulong
734+
> 0B__111 // binary, int
735+
> ```
736+
>
737+
> *end example*
738+
665739
#### 6.4.5.4 Real literals
666740
667741
Real literals are used to write values of types `float`, `double`, and `decimal`.
668742
669743
```ANTLR
670744
Real_Literal
671-
: Decimal_Digit+ '.' Decimal_Digit+ Exponent_Part? Real_Type_Suffix?
672-
| '.' Decimal_Digit+ Exponent_Part? Real_Type_Suffix?
673-
| Decimal_Digit+ Exponent_Part Real_Type_Suffix?
674-
| Decimal_Digit+ Real_Type_Suffix
745+
: Decimal_Digits '.' Decimal_Digits Exponent_Part? Real_Type_Suffix?
746+
| '.' Decimal_Digits Exponent_Part? Real_Type_Suffix?
747+
| Decimal_Digits Exponent_Part Real_Type_Suffix?
748+
| Decimal_Digits Real_Type_Suffix
675749
;
676750
677751
fragment Exponent_Part
678-
: ('e' | 'E') Sign? Decimal_Digit+
752+
: ('e' | 'E') Sign? Decimal_Digits
679753
;
680754
681755
fragment Sign
@@ -706,6 +780,21 @@ The value of a real literal of type `float` or `double` is determined by using t
706780

707781
> *Note*: In a real literal, decimal digits are always required after the decimal point. For example, `1.3F` is a real literal but `1.F` is not. *end note*
708782
783+
> *Example*:
784+
>
785+
> ```csharp
786+
> 1.234_567 // double
787+
> .3e5f // float
788+
> 2_345E-2_0 // double
789+
> 15D // double
790+
> 19.73M // decimal
791+
> 1.F // invalid; ill-formed (parsed as "1." and "F")
792+
> 1.234_ // invalid; no trailing _ allowed in fraction
793+
> .3e5_F // invalid; no trailing _ allowed in exponent
794+
> ```
795+
>
796+
> *end example*
797+
709798
#### 6.4.5.5 Character literals
710799
711800
A character literal represents a single character, and consists of a character in quotes, as in `'a'`.

0 commit comments

Comments
 (0)