From a083648165a7facfeca6f37c023b4b069585acb0 Mon Sep 17 00:00:00 2001
From: Robert Griesemer
An integer literal is a sequence of digits representing an
integer constant.
-An optional prefix sets a non-decimal base:
+For readability, an underscore character
-A floating-point literal is a decimal representation of a
+A floating-point literal is a decimal or hexadecimal representation of a
floating-point constant.
-It has an integer part, a decimal point, a fractional part,
-and an exponent part. The integer and fractional part comprise
-decimal digits; the exponent part is an
+A decimal floating-point literal consists of an integer part (decimal digits),
+a decimal point, a fractional part (decimal digits), and an exponent part
+(
+A hexadecimal floating-point literal consists of a
+For readability, an underscore character
-An imaginary literal is a decimal representation of the imaginary part of a
+An imaginary literal represents the imaginary part of a
complex constant.
-It consists of a
-floating-point literal
-or decimal integer followed
-by the lower-case letter
+For backward compatibility, an imaginary literal's integer part consisting
+entirely of decimal digits (and possibly underscores) is considered a decimal
+integer, even if it starts with a leading _
(U+005F) is considered a letter.
letter = unicode_letter | "_" .
decimal_digit = "0" ⦠"9" .
+binary_digit = "0" | "1" .
octal_digit = "0" ⦠"7" .
hex_digit = "0" ⦠"9" | "A" ⦠"F" | "a" ⦠"f" .
@@ -273,71 +274,156 @@ The following character sequences represent operators
0
for octal, 0x
or
-0X
for hexadecimal. In hexadecimal literals, letters
-a-f
and A-F
represent values 10 through 15.
+An optional prefix sets a non-decimal base: 0b
or 0B
+for binary, 0
, 0o
, or 0O
for octal,
+and 0x
or 0X
for hexadecimal.
+A single 0
is considered a decimal zero.
+In hexadecimal literals, letters a
through f
+and A
through F
represent values 10 through 15.
+_
may appear after
+a base prefix or between successive digits; such underscores do not change
+the literal's value.
-int_lit = decimal_lit | octal_lit | hex_lit .
-decimal_lit = ( "1" ⦠"9" ) { decimal_digit } .
-octal_lit = "0" { octal_digit } .
-hex_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } .
+int_lit = decimal_lit | binary_lit | octal_lit | hex_lit .
+decimal_lit = "0" | ( "1" ⦠"9" ) [ [ "_" ] decimal_digits ] .
+binary_lit = "0" ( "b" | "B" ) [ "_" ] binary_digits .
+octal_lit = "0" [ "o" | "O" ] [ "_" ] octal_digits .
+hex_lit = "0" ( "x" | "X" ) [ "_" ] hex_digits .
+
+decimal_digits = decimal_digit { [ "_" ] decimal_digit } .
+binary_digits = binary_digit { [ "_" ] binary_digit } .
+octal_digits = octal_digit { [ "_" ] octal_digit } .
+hex_digits = hex_digit { [ "_" ] hex_digit } .
42
+4_2
0600
+0_600
+0o600
+0O600 // second character is capital letter 'O'
0xBadFace
+0xBad_Face
+0x_67_7a_2f_cc_40_c6
170141183460469231731687303715884105727
+170_141183_460469_231731_687303_715884_105727
+
+_42 // an identifier, not an integer literal
+42_ // invalid: _ must separate successive digits
+4__2 // invalid: only one _ at a time
+0_xBadFace // invalid: _ must separate successive digits
+
Floating-point literals
+
e
or E
-followed by an optionally signed decimal exponent. One of the
-integer part or the fractional part may be elided; one of the decimal
-point or the exponent may be elided.
e
or E
followed by an optional sign and decimal digits).
+One of the integer part or the fractional part may be elided; one of the decimal point
+or the exponent part may be elided.
+An exponent value exp scales the mantissa (integer and fractional part) by 10exp.
+0x
or 0X
+prefix, an integer part (hexadecimal digits), a radix point, a fractional part (hexadecimal digits),
+and an exponent part (p
or P
followed by an optional sign and decimal digits).
+One of the integer part or the fractional part may be elided; the radix point may be elided as well,
+but the exponent part is required. (This syntax matches the one given in IEEE 754-2008 §5.12.3.)
+An exponent value exp scales the mantissa (integer and fractional part) by 2exp.
+_
may appear after
+a base prefix or between successive digits; such underscores do not change
+the literal value.
+
-float_lit = decimals "." [ decimals ] [ exponent ] |
- decimals exponent |
- "." decimals [ exponent ] .
-decimals = decimal_digit { decimal_digit } .
-exponent = ( "e" | "E" ) [ "+" | "-" ] decimals .
+float_lit = decimal_float_lit | hex_float_lit .
+
+decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
+ decimal_digits decimal_exponent |
+ "." decimal_digits [ decimal_exponent ] .
+decimal_exponent = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
+
+hex_float_lit = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
+hex_mantissa = [ "_" ] hex_digits "." [ hex_digits ] |
+ [ "_" ] hex_digits |
+ "." hex_digits .
+hex_exponent = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
0.
72.40
-072.40 // == 72.40
+072.40 // == 72.40
2.71828
1.e+0
6.67428e-11
1E6
.25
.12345E+5
+1_5. // == 15.0
+0.15e+0_2 // == 15.0
+
+0x1p-2 // == 0.25
+0x2.p10 // == 2048.0
+0x1.Fp+0 // == 1.9375
+0X.8p-0 // == 0.5
+0X_1FFFP-16 // == 0.1249847412109375
+0x15e-2 // == 0x15e - 2 (integer subtraction)
+
+0x.p1 // invalid: mantissa has no digits
+1p-2 // invalid: p exponent requires hexadecimal mantissa
+0x1.5e-2 // invalid: hexadecimal mantissa requires p exponent
+1_.5 // invalid: _ must separate successive digits
+1._5 // invalid: _ must separate successive digits
+1.5_e1 // invalid: _ must separate successive digits
+1.5e_1 // invalid: _ must separate successive digits
+1.5e1_ // invalid: _ must separate successive digits
+
Imaginary literals
+
i
.
+It consists of an integer or
+floating-point literal
+followed by the lower-case letter i
.
+The value of an imaginary literal is the value of the respective
+integer or floating-point literal multiplied by the imaginary unit i.
-imaginary_lit = (decimals | float_lit) "i" .
+imaginary_lit = (decimal_digits | int_lit | float_lit) "i" .
+0
.
+
0i
-011i // == 11i
+0123i // == 123i for backward-compatibility
+0o123i // == 0o123 * 1i == 83i
+0xabci // == 0xabc * 1i == 2748i
0.i
2.71828i
1.e+0i
@@ -345,6 +431,7 @@ imaginary_lit = (decimals | float_lit) "i" .
1E6i
.25i
.12345E+5i
+0x1p-2i // == 0x1p-2 * 1i == 0.25i
@@ -361,6 +448,7 @@ of the character itself,
while multi-character sequences beginning with a backslash encode
values in various formats.
The simplest form represents the single character within the quotes;
since Go source text is Unicode characters encoded in UTF-8, multiple
@@ -370,6 +458,7 @@ a literal a
, Unicode U+0061, value 0x61
, while
'ä'
holds two bytes (0xc3
0xa4
) representing
a literal a
-dieresis, U+00E4, value 0xe4
.
Several backslash escapes allow arbitrary values to be encoded as
ASCII text. There are four ways to represent the integer value
@@ -380,6 +469,7 @@ plain backslash \
followed by exactly three octal digits.
In each case the value of the literal is the value represented by
the digits in the corresponding base.
Although these representations all result in an integer, they have
different valid ranges. Octal escapes must represent a value between
@@ -388,9 +478,11 @@ by construction. The escapes \u
and \U
represent Unicode code points so within them some values are illegal,
in particular those above 0x10FFFF
and surrogate halves.
After a backslash, certain single-character escapes represent special values:
+\a U+0007 alert or bell \b U+0008 backspace @@ -403,6 +495,7 @@ After a backslash, certain single-character escapes represent special values: \' U+0027 single quote (valid escape only within rune literals) \" U+0022 double quote (valid escape only within string literals)+
All other sequences starting with a backslash are illegal inside rune literals.
@@ -446,6 +539,7 @@ A string literal represents a string constant obtained from concatenating a sequence of characters. There are two forms: raw string literals and interpreted string literals. +
Raw string literals are character sequences between back quotes, as in
`foo`
. Within the quotes, any character may appear except
@@ -457,6 +551,7 @@ contain newlines.
Carriage return characters ('\r') inside raw string literals
are discarded from the raw string value.
Interpreted string literals are character sequences between double
quotes, as in "bar"
.
@@ -596,6 +691,7 @@ precision in the language, a compiler may implement them using an
internal representation with limited precision. That said, every
implementation must:
These requirements apply both to literal constants and to the result of evaluating constant expressions.
+-- 2.50.0