5 Lexical conventions [lex]

5.1 Separate translation [lex.separate]

Текст программы хранится в единицах, называемых source files в этом международном стандарте. Исходный файл вместе со всеми headers и исходными файлами included через директиву предварительной обработки #include, за исключением строк исходного кода, пропущенных какой-либо из conditional inclusion директив предварительной обработки, называется файлом translation unit. [ Note: Программу на C ++ не обязательно переводить одновременно. ]end note

[ Note: Ранее переведенные единицы перевода и единицы создания экземпляров могут быть сохранены индивидуально или в библиотеках. Отдельные единицы трансляции программы передают ([basic.link]) посредством (например) вызовов функций, идентификаторы которых имеют внешнюю связь, манипулирования объектами, идентификаторы которых имеют внешнюю связь, или манипулирования файлами данных. Единицы перевода можно переводить отдельно, а затем linked создавать исполняемую программу. ] end note

5.2 Phases of translation [lex.phases]

Приоритет синтаксических правил перевода определяется следующими этапами.12

  1. 1.Физические символы исходного файла сопоставляются, определяемым реализацией способом, с базовым набором исходных символов (вводя символы новой строки для индикаторов конца строки), если это необходимо. Допустимый набор символов физического исходного файла определяется реализацией. Любой символ исходного файла, не входящий в число basic source character set , заменяется символом, обозначающим этот символ. Реализация может использовать любую внутреннюю кодировку при условии, что фактический расширенный символ, встречающийся в исходном файле, и тот же расширенный символ, выраженный в исходном файле как (например, с использованием обозначения), обрабатываются эквивалентно, за исключением случаев, когда эта замена отменяется. ( ) в необработанном строковом литерале.universal-character-nameuniversal-character-name \uXXXX [lex.pptoken]

  2. 2.Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, сращивая физические исходные строки для формирования логических исходных строк. Только последняя обратная косая черта на любой физической исходной строке должна иметь право быть частью такого соединения. За исключением соединений, возвращенных в необработанный строковый литерал, если в результате соединения получается последовательность символов, соответствующая синтаксису a universal-character-name, поведение не определено. Исходный файл, который не является пустым и который не заканчивается символом новой строки или который заканчивается символом новой строки, которому непосредственно предшествует символ обратной косой черты до того, как произойдет какое-либо такое объединение, должен обрабатываться, как если бы дополнительный новый- строчный символ был добавлен к файлу.

  3. 3.Исходный файл разбивается на preprocessing tokens последовательности символов пробела (включая комментарии). Исходный файл не должен заканчиваться токеном частичной предварительной обработки или частичным комментарием.13 Каждый комментарий заменяется одним пробелом. Символы новой строки сохраняются. Сохраняется ли каждая непустая последовательность символов пробела, отличная от новой строки, или заменяется одним символом пробела, не определено. Процесс разделения символов исходного файла на токены предварительной обработки зависит от контекста. [ Example: см. обработку < в #include директиве предварительной обработки. ]end example

  4. 4.Выполняются директивы предварительной обработки, расширяются вызовы макросов и выполняются _­Pragma унарные операторные выражения. Если последовательность символов, соответствующая синтаксису a universal-character-name, создается с помощью token concatenation, поведение не определено. #include Предобработки директива вызывает указанный файл заголовок или источник для обработки от фазы 1 до фазы 4, рекурсивен. Затем все директивы предварительной обработки удаляются.

  5. 5.Каждый член исходного набора символов в символьном литерале или строковом литерале, а также каждая escape-последовательность и universal-character-nameв символьном литерале или необработанном строковом литерале преобразуется в соответствующий член набора символов выполнения ([lex.ccon], [lex.string]); если нет соответствующего члена, он преобразуется в определяемый реализацией член, отличный от нулевого (широкого) символа.14

  6. 6.Смежные лексемы строковых литералов объединяются.

  7. 7.Символы пробела, разделяющие токены, больше не имеют значения. Каждый токен предварительной обработки преобразуется в token. Полученные токены синтаксически и семантически анализируются и переводятся как единица перевода. [ Note: Процесс анализа и перевода токенов может иногда приводить к замене одного токена последовательностью других токенов ([temp.names]). ] [ Исходные файлы, единицы перевода и переведенные единицы перевода не обязательно должны храниться в виде файлов, и нет необходимости иметь какое-либо однозначное соответствие между этими объектами и любым внешним представлением. Описание носит только концептуальный характер и не указывает конкретную реализацию. ]end noteNote: end note

  8. 8.Переведенные единицы перевода и единицы создания экземпляров объединяются следующим образом: [ Note: Некоторые или все из них могут быть предоставлены из библиотеки. ] Каждая переведенная единица перевода проверяется, чтобы составить список требуемых экземпляров. [ Это может включать экземпляры, которые были . ] Определения необходимых шаблонов находятся. Это определяется реализация, требуется ли источник перевода единиц , содержащих эти определения должны быть доступны. [ Реализация могла бы закодировать достаточную информацию в переведенной единице перевода, чтобы гарантировать, что источник здесь не требуется. ] Все необходимые экземпляры выполняются для создания . [ Они похожи на переведенные единицы перевода, но не содержат ссылок на неустановленные шаблоны и не содержат определений шаблонов. ] Программа плохо сформирована, если какой-либо экземпляр не удается. end noteNote: explicitly requested end noteNote: end noteinstantiation unitsNote: end note

  9. 9.Все ссылки на внешние сущности разрешены. Компоненты библиотеки связаны для соответствия внешним ссылкам на объекты, не определенные в текущем переводе. Весь такой вывод транслятора собирается в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения.

Реализации должны вести себя так, как если бы происходили эти отдельные фазы, хотя на практике разные фазы могут быть объединены.

Токен частичной предварительной обработки может возникнуть из исходного файла, заканчивающегося первой частью многосимвольного токена, для которого требуется завершающая последовательность символов, например a, в header-name котором отсутствует закрывающее " или >. Частичный комментарий может возникнуть из исходного файла, заканчивающегося незакрытым /* комментарием.

Реализации не требуется преобразовывать все несоответствующие исходные символы в один и тот же символ выполнения.

5.3 Character sets [lex.charset]

Он basic source character set состоит из 96 символов: пробела, управляющих символов, представляющих горизонтальную табуляцию, вертикальную табуляцию, подачу страницы и новую строку, а также следующие 91 графический символ:15

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '

Эта universal-character-nameконструкция позволяет давать имена другим персонажам.

hex-quad:
	hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
universal-character-name:
	\u hex-quad
	\U hex-quad hex-quad

Характер обозначены теми universal-character-name \UNNNNNNNN , что персонаж, характер которого сокращенное наименование в ИСО / МЭК 10646 является NNNNNNNN; символ, обозначенный знаком, universal-character-name \uNNNN является тем символом, которому соответствует короткое имя символа в ISO / IEC 10646 0000NNNN. Если шестнадцатеричное значение для a universal-character-nameсоответствует суррогатной кодовой точке (в диапазоне 0xD800–0xDFFF включительно), программа имеет неправильный формат. Кроме того, если шестнадцатеричное значение для universal-character-nameСнаружи c-char-sequence, s-char-sequenceили r-char-sequenceиз символа или строк литералов соответствуют управляющему символу (в любом из диапазонов 0x00-0x1F или 0x7F-0x9F, оба включительно) или к символу в основном исходном характере установлен, программа сформирована неправильно.16

Каждый из basic execution character set и basic execution wide-character set должен содержать все элементы базового исходного набора символов плюс управляющие символы, представляющие предупреждение, возврат и возврат каретки, плюс null character (соответственно null wide character), значение которого равно 0. Для каждого базового набора символов выполнения значения члены должны быть неотрицательными и отличными друг от друга. Как в исходном, так и в исполнительном базовых наборах символов значение каждого символа после 0 в приведенном выше списке десятичных цифр должно быть на единицу больше, чем значение предыдущего. execution character set И execution wide-character set являются осуществлением определенных надмножеств базового набора символов и выполнения основного набора выполнения широких символов, соответственно. Значения элементов наборов символов выполнения и наборов дополнительных элементов зависят от локали.

Глифы для элементов основного исходного набора символов предназначены для идентификации символов из подмножества ISO / IEC 10646, которое соответствует набору символов ASCII. Однако, поскольку отображение символов исходного файла в исходный набор символов (описанное в фазе перевода 1) задано как определяемое реализацией, требуется реализация, чтобы задокументировать, как основные исходные символы представлены в исходных файлах.

Последовательность символов, напоминающая a universal-character-nameв a r-char-sequence, не образует a universal-character-name.

5.4 Preprocessing tokens [lex.pptoken]

preprocessing-token:
	header-name
	identifier
	pp-number
	character-literal
	user-defined-character-literal
	string-literal
	user-defined-string-literal
	preprocessing-op-or-punc
	each non-white-space character that cannot be one of the above

Каждый токен предварительной обработки, преобразованный в a, token должен иметь лексическую форму ключевого слова, идентификатора, литерала, оператора или пунктуатора.

Токен предварительной обработки - это минимальный лексический элемент языка на этапах преобразования с 3 по 6. Категории токена предварительной обработки: имена заголовков, идентификаторы, числа предварительной обработки, символьные литералы (включая определяемые пользователем символьные литералы), строковые литералы (включая пользовательские литералы). определенные строковые литералы), операторы предварительной обработки и знаки препинания, а также отдельные символы без пробелов, которые лексически не соответствуют другим категориям токенов предварительной обработки. Если символ ' или " соответствует последней категории, поведение не определено. Токены предварительной обработки могут быть разделены пробелом; он состоит из commentsсимволов или пробелов (пробел, горизонтальная табуляция, новая строка, вертикальная табуляция и перевод страницы), или и того, и другого. Как описано в пункте [cpp], в определенных обстоятельствах во время фазы трансляции 4 пробелы (или их отсутствие) служат чем-то большим, чем разделение токенов предварительной обработки. Пробел может появляться в токене предварительной обработки только как часть имени заголовка или между кавычками в символьном литерале или строковом литерале.

Если входной поток был проанализирован на токены предварительной обработки до заданного символа:

  • Если следующий символ начинает последовательность символов, которая может быть префиксом и начальной двойной кавычкой необработанного строкового литерала, например R", следующий токен предварительной обработки должен быть необработанным строковым литералом. Между начальным и конечным символами двойных кавычек необработанной строки любые преобразования, выполненные на этапах 1 и 2 ( universal-character-names и сращивание строк), отменяются; это обращение применяется до того d-char, как r-charбудут идентифицированы какие- либо ограничивающие скобки, или. Необработанный строковый литерал определяется как кратчайшая последовательность символов, соответствующая шаблону необработанной строки.

    encoding-prefixopt R raw-string
    
  • В противном случае, если следующие три символа <​::​ и последующий символ не является ни : ни >, то < рассматривается как предварительная обработкой маркера самого по себе , а не в качестве первого символа альтернативных маркеров <:.

  • В противном случае следующий токен предварительной обработки - это самая длинная последовательность символов, которая может составлять токен предварительной обработки, даже если это приведет к сбою дальнейшего лексического анализа, за исключением того, что a header-nameформируется только внутри a #include directive.

[Example:

#define R "x"
const char* s = R"y";           // ill-formed raw string, not "x" "y"

end example]

[ Example: Фрагмент программы 0xe+foo анализируются как предварительная обработкой числа лексем (тот , который не является допустимым с плавающим или целым числом буквальных маркеров), даже несмотря на то синтаксическим анализ в виде три Препроцессирования маркеров 0xe, +и foo может произвести корректное выражение (например, если foo были определены макро как 1). Точно так же фрагмент программы 1E1 анализируется как номер предварительной обработки (тот, который является допустимым плавающим литеральным токеном), независимо от того, E является ли это именем макроса. ] end example

[ Example: Фрагмент программы x+++++y анализируется как x ++ ++ + y, который, если x и y имеет целочисленные типы, нарушает ограничение на операторы приращения, даже если синтаксический анализ x ++ + ++ y может дать правильное выражение. ] end example

5.5 Alternative tokens [lex.digraph]

Для некоторых операторов и знаков препинания предусмотрены альтернативные представления токенов.17

Во всех отношениях языка каждый альтернативный токен ведет себя, соответственно, так же, как его основной токен, за исключением его написания.18 Набор альтернативных токенов определен в таблице 1.

Таблица 1 - Альтернативные токены
Альтернатива Начальный Альтернатива Начальный Альтернатива Начальный
<% { and && and_­eq &=
%> } bitor | or_­eq |=
<: [ or || xor_­eq ^=
:> ] xor ^ not !
%: # compl ~ not_­eq !=
%:%: ## bitand &

К ним относятся «орграфы» и дополнительные зарезервированные слова. Термин «орграф» (токен, состоящий из двух символов) не является полностью описательным, поскольку один из альтернативных токенов предварительной обработки %:%: и, конечно же, несколько основных токенов содержат два символа. Тем не менее, те альтернативные токены, которые не являются лексическими ключевыми словами, в просторечии известны как «диграфы».

Таким образом, “stringized” значения [ и <: будут разными при сохранении исходного написания, но в противном случае токены можно свободно менять местами.

5.6 Tokens [lex.token]

token:
	identifier
	keyword
	literal
	operator
	punctuator

Есть пять видов токенов: идентификаторы, ключевые слова, литералы,19 операторы и другие разделители. Пробелы, горизонтальные и вертикальные табуляции, новые строки, переводы форм и комментарии (вместе «пробелы»), как описано ниже, игнорируются, за исключением тех случаев, когда они служат для разделения токенов. [ Note: Некоторый пробел требуется для разделения смежных идентификаторов, ключевых слов, числовых литералов и альтернативных токенов, содержащих буквенные символы. ]end note

Литералы включают строки, символьные и числовые литералы.

5.7 Comments [lex.comment]

Персонажи /* начинают комментарий, который заканчивается символами */. Эти комментарии не гнездятся. Символы // начинают комментарий, который заканчивается непосредственно перед следующим символом новой строки. Если в таком комментарии есть символ перевода страницы или вертикальной табуляции, между ним и новой строкой, завершающей комментарий, должны появляться только символы пробела; Диагностика не требуется. [ Note: Комментарий символов //, /*и */ не имеют особого значения в пределах // комментария и обрабатываются так же , как другие символы. Точно так же символы // и не /* имеют особого значения внутри /* комментария. ] end note

5.9 Preprocessing numbers [lex.ppnumber]

pp-number:
	digit
	. digit
	pp-number digit
	pp-number identifier-nondigit
	pp-number ' digit
	pp-number ' nondigit
	pp-number e sign
	pp-number E sign
	pp-number p sign
	pp-number P sign
	pp-number .

Предварительная обработка числовых токенов лексически включает все integer literal токены и все floating literal токены.

Число предварительной обработки не имеет типа или значения; он получает как после успешного преобразования в токен целочисленного литерала, так и в токен плавающего литерала.

5.10 Identifiers [lex.name]

identifier:
	identifier-nondigit
	identifier identifier-nondigit
	identifier digit
identifier-nondigit:
	nondigit
	universal-character-name
nondigit: one of
	a b c d e f g h i j k l m
	n o p q r s t u v w x y z
	A B C D E F G H I J K L M
	N O P Q R S T U V W X Y Z _
digit: one of
	0 1 2 3 4 5 6 7 8 9

Идентификатор - это произвольно длинная последовательность букв и цифр. Каждый universal-character-nameв идентификаторе должен обозначать символ, кодировка которого в ISO 10646 попадает в один из диапазонов, указанных в таблице 2. Начальный элемент не должен быть universal-character-name обозначением символа, кодировка которого попадает в один из диапазонов, указанных в таблице 3. Прописные и строчные буквы различаются. Все персонажи значительны.21

Таблица 2 - допустимые диапазоны символов
00A8 00AA 00AD 00AF 00B2-00B5
00B7-00BA 00BC-00BE 00C0-00D6 00D8-00F6 00F8-00FF
0100-167F 1681-180D 180F-1FFF
200B-200D 202A-202E 203F-2040 2054 2060-206F
2070-218F 2460-24FF 2776-2793 2C00-2DFF 2E80-2FFF
3004-3007 3021-302F 3031-D7FF
F900-FD3D FD40-FDCF FDF0-FE44 FE47-FFFD
10000-1FFFD 20000-2FFFD 30000-3FFFD 40000-4FFFD 50000-5FFFD
60000-6FFFD 70000-7FFFD 80000-8FFFD 90000-9FFFD A0000-AFFFD
B0000-BFFFD C0000-CFFFD D0000-DFFFD E0000-EFFFD
Таблица 3 - диапазоны запрещенных изначально символов (объединение символов)
0300-036F 1DC0-1DFF 20D0-20FF FE20-FE2F

Идентификаторы в таблице 4 имеют особое значение при появлении в определенном контексте. Когда они упоминаются в грамматике, эти идентификаторы используются явно, а не с использованием identifierграмматической продукции. Если не указано иное, любая двусмысленность относительно того, identifierимеет ли данное значение особое значение, разрешается интерпретировать токен как обычный identifier.

Таблица 4 - Идентификаторы со специальным значением
override final

Кроме того, некоторые идентификаторы зарезервированы для использования реализациями C ++ и не должны использоваться иначе; Диагностика не требуется.

  • Каждый идентификатор, содержащий двойное подчеркивание или начинающийся с подчеркивания, за которым следует заглавная буква , зарезервирован для реализации для любого использования. __

  • Каждый идентификатор, начинающийся с подчеркивания, зарезервирован для реализации для использования в качестве имени в глобальном пространстве имен.

В системах, в которых компоновщики не могут принимать расширенные символы, для universal-character-nameформирования допустимых внешних идентификаторов может использоваться кодировка . Например, для кодирования \u в файле universal-character-name. Расширенные символы могут создавать длинный внешний идентификатор, но C ++ не устанавливает ограничения на перевод значимых символов для внешних идентификаторов. В C ++ буквы верхнего и нижнего регистра считаются разными для всех идентификаторов, включая внешние идентификаторы.

5.11 Keywords [lex.key]

Идентификаторы, показанные в таблице 5 , зарезервированы для использования в качестве ключевых слов (то есть они безусловно рассматриваются как ключевые слова на этапе 7), за исключением attribute-token:

Таблица 5 - Ключевые слова
alignas continue friend register true
alignof decltype goto reinterpret_­cast try
asm default if return typedef
auto delete inline short typeid
bool do int signed typename
break double long sizeof union
case dynamic_­cast mutable static unsigned
catch else namespace static_­assert using
char enum new static_­cast virtual
char16_­t explicit noexcept struct void
char32_­t export nullptr switch volatile
class extern operator template wchar_­t
const false private this while
constexpr float protected thread_­local
const_­cast for public throw

[ И ключевые слова не используются , но зарезервированы для использования в будущем. ]Note: export register end note

Кроме того, альтернативные представления, показанные в таблице 6 для некоторых операторов и знаков препинания ([lex.digraph]), зарезервированы и не могут использоваться иначе:

Таблица 6 - Альтернативные представления
and and_­eq bitand bitor compl not
not_­eq or or_­eq xor xor_­eq

5.12 Operators and punctuators [lex.operators]

Лексическое представление программ C ++ включает ряд токенов предварительной обработки, которые используются в синтаксисе препроцессора или преобразуются в токены для операторов и знаков препинания:

preprocessing-op-or-punc: one of
	{ 	} 	[ 	] 	# 	## 	( 	)
	<: 	:> 	<% 	%> 	%: 	%:%: 	; 	: 	...
	new 	delete 	? 	:: 	. 	.*
	+ 	- 	* 	/ 	% 	^	& 	| 	~
	! 	= 	< 	> 	+= 	-= 	*= 	/= 	%=
	^= 	&= 	|= 	<< 	>> 	>>= 	<<= 	== 	!=
	<= 	>= 	&& 	|| 	++ 	-- 	, 	->* 	->
	and 	and_eq 	bitand 	bitor 	compl 	not 	not_eq
	or 	or_eq 	xor 	xor_eq

Каждый preprocessing-op-or-puncконвертируется в один токен формата translation phase 7.

5.13 Literals [lex.literal]

5.13.1 Kinds of literals [lex.literal.kinds]

Термин «буквальный» в данном международном стандарте обычно обозначает те токены, которые называются «константами» в ISO C.

5.13.2 Integer literals [lex.icon]

integer-literal:
	binary-literal integer-suffixopt
	octal-literal integer-suffixopt
	decimal-literal integer-suffixopt
	hexadecimal-literal integer-suffixopt
binary-literal:
	0b binary-digit
	0B binary-digit
	binary-literal 'opt binary-digit
octal-literal:
	0
	octal-literal 'opt octal-digit
decimal-literal:
	nonzero-digit
	decimal-literal 'opt digit
hexadecimal-literal:
	hexadecimal-prefix hexadecimal-digit-sequence
binary-digit:
	0
	1
octal-digit: one of
	0  1  2  3  4  5  6  7
nonzero-digit: one of
	1  2  3  4  5  6  7  8  9
hexadecimal-prefix: one of
	0x  0X
hexadecimal-digit-sequence:
	hexadecimal-digit
	hexadecimal-digit-sequence 'opt hexadecimal-digit
hexadecimal-digit: one of
	0  1  2  3  4  5  6  7  8  9
	a  b  c  d  e  f
	A  B  C  D  E  F
integer-suffix:
	unsigned-suffix long-suffixopt 
	unsigned-suffix long-long-suffixopt 
	long-suffix unsigned-suffixopt 
	long-long-suffix unsigned-suffixopt
unsigned-suffix: one of
	u  U
long-suffix: one of
	l  L
long-long-suffix: one of
	ll  LL

An integer literal - это последовательность цифр, не имеющая точки или экспоненты, с необязательными разделяющими одинарными кавычками, которые игнорируются при определении ее значения. Целочисленный литерал может иметь префикс, определяющий его основу, и суффикс, определяющий его тип. Лексически первая цифра последовательности цифр является наиболее значимой. A binary integer literal (с основанием два) начинается с 0b или 0B и состоит из последовательности двоичных цифр. octal integer literal (База восемь) начинается с цифрой 0 и состоит из последовательности восьмеричных цифр.23 A decimal integer literal (основание десять) начинается с цифры, отличной от 0 и состоит из последовательности десятичных цифр. hexadecimal integer literal (Основание шестнадцать) начинается с 0x или 0X и состоит из последовательности шестнадцатеричных цифр, которые включают в себя десятичные цифры и буквы a пути f и A через F с десятичными значениями десять через пятнадцать. [ Example: Число двенадцать может быть записано 12, 014, 0XC, или 0b1100. Целочисленные литералы 1048576, 1'048'576, 0X100000, 0x10'0000, и 0'004'000'000 все они имеют одинаковое значение. ]end example

Тип целочисленного литерала - это первый из соответствующего списка в таблице, 7 в котором может быть представлено его значение.

Таблица 7 - Типы целочисленных литералов
СуффиксДесятичный литералДвоичный, восьмеричный или шестнадцатеричный литерал
никто int int
long int unsigned int
long long int long int
unsigned long int
long long int
unsigned long long int
u или U unsigned int unsigned int
unsigned long int unsigned long int
unsigned long long int unsigned long long int
l или L long int long int
long long int unsigned long int
long long int
unsigned long long int
Оба u или U unsigned long int unsigned long int
и l или L unsigned long long int unsigned long long int
ll или LL long long int long long int
unsigned long long int
Оба u или U unsigned long long int unsigned long long int
и ll или LL

Если целочисленный литерал не может быть представлен каким-либо типом в своем списке, а extended integer type может представлять его значение, он может иметь этот расширенный целочисленный тип. Если все типы в списке для целочисленного литерала подписаны, расширенный целочисленный тип должен быть подписан. Если все типы в списке для целочисленного литерала беззнаковые, расширенный целочисленный тип должен быть беззнаковым. Если список содержит как знаковые, так и беззнаковые типы, расширенный целочисленный тип может быть знаковым или беззнаковым. Программа плохо сформирована, если одна из ее единиц трансляции содержит целочисленный литерал, который не может быть представлен ни одним из разрешенных типов.

Цифры 8 и 9 не являются восьмеричными цифрами.

5.13.3 Character literals [lex.ccon]

character-literal:
	encoding-prefixopt ' c-char-sequence '
encoding-prefix: one of
	u8  u  U  L
c-char-sequence:
	c-char
	c-char-sequence c-char
c-char:
	any member of the source character set except
		the single-quote ', backslash \, or new-line character
	escape-sequence
	universal-character-name
escape-sequence:
	simple-escape-sequence
	octal-escape-sequence
	hexadecimal-escape-sequence
simple-escape-sequence: one of
	\'  \"  \?  \\
	\a  \b  \f  \n  \r  \t  \v
octal-escape-sequence:
	\ octal-digit
	\ octal-digit octal-digit
	\ octal-digit octal-digit octal-digit
hexadecimal-escape-sequence:
	\x hexadecimal-digit
	hexadecimal-escape-sequence hexadecimal-digit

Символьный литерал представляет собой один или несколько символов , заключенные в одинарные кавычки, как и в 'x', необязательно предшествует u8, u, U, или L, как в u8'w', u'x', U'y', или L'z', соответственно.

Символьный литерал , который не начинается с u8, u, Uили L это ordinary character literal. Обычный символьный литерал, содержащий единственный c-charпредставимый в наборе символов выполнения, имеет тип charсо значением, равным числовому значению кодировки c-charв наборе символов выполнения. Обычный символьный литерал, содержащий более одного, c-char- это multicharacter literal. Multicharacter буквальный, или обычные символьный литерал , содержащий один c-charне представимы в наборе символов исполнения, условно-поддерживаются, имеет тип int, и имеет определенную реализацию значения.

Символьный литерал, начинающийся с u8, например u8'w', является символьным литералом типа char, известного как UTF-8 character literal. Значение символьного литерала UTF-8 равно его значению кодовой точки ISO 10646 при условии, что значение кодовой точки может быть представлено одной единицей кода UTF-8 (то есть при условии, что оно находится в элементах управления C0 и базовом латинском Unicode. блокировать). Если значение не может быть представлено одной единицей кода UTF-8, программа имеет неправильный формат. Символьный литерал UTF-8, содержащий несколько, c-chars имеет неправильный формат.

Символьный литерал, начинающийся с буквы u, например u'x', является символьным литералом типа char16_­t. Значение char16_­t символьного литерала, содержащего один c-char, равно его значению кодовой точки ISO 10646 при условии, что кодовая точка может быть представлена ​​одной 16-битной кодовой единицей. (То есть при условии, что это базовая кодовая точка многоязычной плоскости.) Если значение не может быть представлено в пределах 16 бит, программа сформирована неправильно. char16_­t Литера , содержащие несколько c-chars плохо сформировано.

Символьный литерал, начинающийся с буквы U, например U'y', является символьным литералом типа char32_­t. Значение char32_­t символьного литерала, содержащего один c-char, равно его значению кодовой точки ISO 10646. char32_­t Литера , содержащие несколько c-chars плохо сформировано.

Символьный литерал, начинающийся с буквы L, например L'z', - это wide-character literal. Литерал с широкими символами имеет тип wchar_­t.24 Значение литерала расширенных символов, содержащего один, c-charимеет значение, равное числовому значению кодировки c-charв наборе расширенных символов выполнения, если только c-charне имеет представления в наборе расширенных символов выполнения, и в этом случае значение равно определяется реализацией. [ Note: Тип wchar_­t может представлять все элементы расширенного набора символов выполнения (см. [basic.fundamental]). ] Значение литерала для широких символов, содержащего несколько, определяется реализацией.end notec-chars

Некоторые неграфические символы, одиночная кавычка ', двойные кавычки ", вопросительный знак ?,25 и обратный слэш \, могут быть представлены в соответствии с таблицей 8. Двойные кавычки " и вопросительный знак ?могут быть представлены сами по себе или с помощью управляющих последовательностей \" и \? соответственно, но одинарная кавычка ' и обратная косая черта \ должны быть представлены управляющими последовательностями \' и \\ соответственно. Управляющие последовательности, в которых символ, следующий за обратной косой чертой, не указан в таблице 8 , поддерживаются условно с семантикой, определяемой реализацией. Управляющая последовательность определяет один символ.

Таблица 8 - escape-последовательности
новая линия NL (LF) \n
горизонтальная табуляция HT \t
вертикальная табуляция VT \v
Backspace BS \b
возврат каретки CR \r
подача формы FF \f
тревога BEL \a
обратная косая черта \ \\
вопросительный знак ? \?
одинарная кавычка ' \'
двойная кавычка " \"
восьмеричное число ооо \ooo
шестнадцатеричный номер ххх \xhhh

Escape \ooo состоит из обратной косой черты, за которой следуют одна, две или три восьмеричных цифры, которые используются для указания значения желаемого символа. Escape \xhhh состоит из обратной косой черты, за которой x следует одна или несколько шестнадцатеричных цифр, которые используются для указания значения желаемого символа. Количество цифр в шестнадцатеричной последовательности не ограничено. Последовательность восьмеричных или шестнадцатеричных цифр завершается первым символом, который не является восьмеричной или шестнадцатеричной цифрой соответственно. Значение символьного литерала определяется реализацией, если оно выходит за пределы определенного реализацией диапазона, определенного для char (для символьных литералов без префикса) или wchar_­t (для символьных литералов с префиксом L). [ Note: Если значение символа буквального префикса u, u8или U находится вне диапазона , определенный для его типа, программа плохо сформировано. ]end note

A universal-character-nameпереводится в кодировку указанного символа в соответствующем наборе символов выполнения. Если такой кодировки нет, universal-character-nameпреобразуется в кодировку, определяемую реализацией. [ Note: На этапе перевода 1 universal-character-nameсимвол a вводится всякий раз, когда в исходном тексте встречается фактический расширенный символ. Поэтому все расширенные символы описываются в терминах universal-character-names. Однако фактическая реализация компилятора может использовать свой собственный набор символов, если будут получены те же результаты. ] end note

Они предназначены для наборов символов, в которых символ не помещается в один байт.

Использование escape-последовательности для вопросительного знака поддерживается для совместимости с ISO C ++ 2014 и ISO C.

5.13.4 Floating literals [lex.fcon]

floating-literal:
	decimal-floating-literal
	hexadecimal-floating-literal
decimal-floating-literal:
	fractional-constant exponent-partopt floating-suffixopt
	digit-sequence exponent-part floating-suffixopt
hexadecimal-floating-literal:
	hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffixopt
	hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffixopt
fractional-constant:
	digit-sequenceopt . digit-sequence
	digit-sequence .
hexadecimal-fractional-constant:
	hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
	hexadecimal-digit-sequence .
exponent-part:
	e signopt digit-sequence
	E signopt digit-sequence
binary-exponent-part:
	p signopt digit-sequence
	P signopt digit-sequence
sign: one of
	+  -
digit-sequence:
	digit
	digit-sequence 'opt digit
floating-suffix: one of
	f  l  F  L

Плавающий буквальным состоит из необязательного префикса указав основание, целую часть, точку базисной, фракцию , часть, в , , или , необязательно целочисленный показатель степень, и необязательный суффикс типа. Целая и дробная части состоят из последовательности десятичных (основание десять) цифр, если нет префикса, или шестнадцатеричных (основание шестнадцати) цифр, если префиксом является или . Плавающий литерал - это a в первом случае и a во втором. Необязательное разделение одинарных кавычек в или игнорируется при определении его значения. [ Плавающие литералы и имеют одинаковое значение. ] Можно опустить целую или дробную часть (но не обе сразу). В десятичном литерале с плавающей запятой можно опустить либо точку счисления, либо букву, либо и показатель степени (но не оба сразу). В шестнадцатеричном литерале с плавающей запятой можно опустить точку счисления (но не показатель степени). Целая часть, необязательная точка счисления и необязательная дробная часть образуют плавающий литерал. В десятичном литерале с плавающей запятой показатель степени, если он присутствует, указывает степень 10, с помощью которой следует масштабировать мантиссу. В шестнадцатеричном литерале с плавающей запятой показатель степени указывает степень двойки, на которую следует масштабировать мантиссу. [ Плавающие литералы и имеют одинаковое значение. ] Если масштабированное значение находится в диапазоне представляемых значений для своего типа, результатом является масштабированное значение, если оно представимо, иначе большее или меньшее представляемое значение, ближайшее к масштабируемому значению, выбранное способом, определяемым реализацией. Тип плавающего литерала не указан явно суффиксом. Суффиксы и укажите , суффиксы и укажите . Если масштабируемое значение не входит в диапазон представимых значений для его типа, программа имеет неправильный формат. e E p P 0x 0X decimal floating literal hexadecimal floating literal digit-sequencehexadecimal-digit-sequenceExample: 1.602'176'565e-19 1.602176565e-19 end example e E significand Example: 49.625 0xC.68p+2 end example double f F float l L long double

5.13.5 String literals [lex.string]

string-literal:
	encoding-prefixopt " s-char-sequenceopt "
	encoding-prefixopt R raw-string
s-char-sequence:
	s-char
	s-char-sequence s-char
s-char:
	any member of the source character set except
		the double-quote ", backslash \, or new-line character
	escape-sequence
	universal-character-name
raw-string:
	" d-char-sequenceopt ( r-char-sequenceopt ) d-char-sequenceopt "
r-char-sequence:
	r-char
	r-char-sequence r-char
r-char:
	any member of the source character set, except
		a right parenthesis ) followed by the initial d-char-sequence
		(which may be empty) followed by a double quote ".
d-char-sequence:
	d-char
	d-char-sequence d-char
d-char:
	any member of the basic source character set except:
		space, the left parenthesis (, the right parenthesis ), the backslash \,
		and the control characters representing horizontal tab,
		vertical tab, form feed, and newline.

string-literalПредставляет собой последовательность символов (как определено в [lex.ccon]) в двойных кавычках, при необходимости с приставкой R, u8, u8R, u, uR, U, UR, L, или LR, как в "...", R"(...)", u8"...", u8R"**(...)**", u"...", uR"*~(...)*~", U"...", UR"zzz(...)zzz", L"...", или LR"(...)", соответственно.

string-literal, Что имеет в префиксе это . Символ служит разделителем. Окончание a - это та же последовательность символов, что и начальная . А должен состоять максимум из 16 знаков. R raw string literald-char-sequenced-char-sequenceraw-stringd-char-sequenced-char-sequence

[ Note: Символы '(' и ')' разрешены в raw-string. Таким образом, R"delimiter((a|b))delimiter" эквивалентно "(a|b)". ] end note

[ Note: Новая строка исходного файла в необработанном строковом литерале приводит к новой строке в результирующем строковом литерале выполнения. Предполагая, что в начале строк в следующем примере нет пробелов, утверждение будет успешным:

const char* p = R"(a\
b
c)";
assert(std::strcmp(p, "a\\\nb\nc") == 0);

end note]

[ Example: Необработанная строка

R"a(
)\
a"
)a"

эквивалентно "\n)\\\na\"\n". Необработанная строка

R"(??)"

эквивалентно "\?\?". Необработанная строка

R"#(
)??="
)#"

эквивалентно "\n)\?\?=\"\n". ] end example

После фазы трансляции 6 элемент a string-literal, который не начинается с символа encoding-prefixan ordinary string literal, инициализируется заданными символами.

string-literal, Который начинается с u8, таких как u8"asdf", является UTF-8 string literal.

Обычные строковые литералы и строковые литералы UTF-8 также называются узкими строковыми литералами. Узкий строковый литерал имеет тип «массив из n const char», где n - размер строки, как определено ниже, и имеет static storage duration.

Для строкового литерала UTF-8 каждый последующий элемент object representation имеет значение соответствующей кодовой единицы кодировки строки UTF-8.

A, string-literalкоторый начинается с u, например u"asdf", является char16_­t строковым литералом. char16_­t Строковый литерал имеет тип «массив n const char16_­t», где n это размер строки , как определено ниже; он инициализируется заданными символами. Один c-charможет содержать более одного char16_­t символа в виде суррогатных пар.

A, string-literalкоторый начинается с U, например U"asdf", является char32_­t строковым литералом. char32_­t Строковый литерал имеет тип «массив n const char32_­t», где n это размер строки , как определено ниже; он инициализируется заданными символами.

string-literal, Который начинается с L, таких как L"asdf", является wide string literal. Широкий строковый литерал имеет тип «массив », где - размер строки, как определено ниже; он инициализируется заданными символами. n const wchar_­t n

В translation phase 6, смежные string-literals объединяются. Если оба string-literals имеют одинаковые значения encoding-prefix, полученный конкатенированный строковый литерал будет иметь это encoding-prefix. Если у одного string-literalнет encoding-prefix, он рассматривается как один string-literalиз тех же, encoding-prefixчто и другой операнд. Если токен строкового литерала UTF-8 соседствует с токеном широкого строкового литерала, программа имеет неправильный формат. Любые другие конкатенации условно поддерживаются с поведением, определяемым реализацией. [ Note: Эта конкатенация является интерпретацией, а не преобразованием. Поскольку интерпретация происходит на этапе перевода 6 (после того, как каждый символ строкового литерала был переведен в значение из соответствующего набора символов), string-literalисходная грубость a не влияет на интерпретацию или правильность конкатенации. ] В таблице есть несколько примеров допустимых конкатенаций.end note 9

Таблица 9 - конкатенации строковых литералов
Источник Средства Источник Средства Источник Средства
u"a" u"b" u"ab" U"a" U"b" U"ab" L"a" L"b" L"ab"
u"a" "b" u"ab" U"a" "b" U"ab" L"a" "b" L"ab"
"a" u"b" u"ab" "a" U"b" U"ab" "a" L"b" L"ab"

Символы в составных строках сохраняются отдельно.

[Example:

"\xA" "B"

содержит два символа '\xA' и 'B' после объединения (а не один шестнадцатеричный символ '\xAB'). ]end example

После любой необходимой конкатенации к каждому строковому литералу добавляется in translation phase 7, '\0' чтобы программы, просматривающие строку, могли найти ее конец.

Escape-последовательности и universal-character-names в необработанных строковых литералах имеют то же значение, что и в character literals, за исключением того, что одинарная кавычка ' может быть представлена ​​либо сама по себе, либо с помощью escape-последовательности \', а двойной кавычке " должен предшествовать a \, и за исключением того, что a universal-character-nameв char16_­t строковом литерале может дать суррогатную пару. В узком строковом литерале a universal-character-nameможет отображаться более чем на один char элемент из-за multibyte encoding. Размер char32_­t строкового литерала or - это общее количество управляющих последовательностей universal-character-names, и других символов, плюс один для завершающего U'\0' или L'\0'. Размер char16_­t строкового литерала - это общее количество управляющих последовательностей, universal-character-namesи других символов, плюс один для каждого символа, требующего суррогатной пары, плюс один для завершения u'\0'. [ Note: Размер char16_­t строкового литерала - это количество кодовых единиц, а не количество символов. ] В и строки литералов, любой должен быть в пределах до . Размер узкого строкового литерала - это общее количество escape-последовательностей и других символов, плюс по крайней мере один для многобайтовой кодировки каждого , плюс один для завершения . end note char32_­t char16_­tuniversal-character-names 0x0 0x10FFFFuniversal-character-name '\0'

string-literalРезультатом оценки является объект строкового литерала со статической продолжительностью хранения, инициализированный заданными символами, как указано выше. Все ли строковые литералы различны (то есть хранятся в неперекрывающихся объектах) и не определено ли последовательные вычисления одного и string-literalтого же объекта или другого объекта. [ Эффект от попытки изменить строковый литерал не определен. ]Note: end note

5.13.6 Boolean literals [lex.bool]

boolean-literal:
	false
	true

Логические литералы - это ключевые слова false и true. Такие литералы являются prvalue и имеют тип bool.

5.13.7 Pointer literals [lex.nullptr]

pointer-literal:
	nullptr

Литерал указателя - это ключевое слово nullptr. Это значение типа std​::​nullptr_­t. [ Note: std​::​nullptr_­t - это отдельный тип, который не является ни типом указателя, ни указателем на тип члена; скорее, prvalue этого типа является константой нулевого указателя и может быть преобразовано в значение нулевого указателя или значение указателя на нулевой член. Смотрите [conv.ptr] и [conv.mem]. ]end note

5.13.8 User-defined literals [lex.ext]

user-defined-literal:
	user-defined-integer-literal
	user-defined-floating-literal
	user-defined-string-literal
	user-defined-character-literal
user-defined-integer-literal:
	decimal-literal ud-suffix
	octal-literal ud-suffix
	hexadecimal-literal ud-suffix
	binary-literal ud-suffix
user-defined-floating-literal:
	fractional-constant exponent-partopt ud-suffix
	digit-sequence exponent-part ud-suffix
	hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix
	hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix
user-defined-string-literal:
	string-literal ud-suffix
user-defined-character-literal:
	character-literal ud-suffix
ud-suffix:
	identifier

Если токен соответствует обоим user-defined-literalи другому literalтипу, он считается последним. [ Example: 123_­km - это user-defined-literal, но 12LL это - integer-literal. ] Синтаксический нетерминал, предшествующий в a, считается самой длинной последовательностью символов, которая может соответствовать этому нетерминальному. end exampleud-suffixuser-defined-literal

A user-defined-literalрассматривается как вызов literal operator или literal operator template. Чтобы определить форму этого вызова для заданного user-defined-literal L с ud-suffix X, literal-operator-idищется буквальный идентификатор суффикса X в контексте L использования правил для unqualified name lookup. Позвольте S быть набором объявлений, найденных этим поиском. S не должно быть пустым.

Если L это a user-defined-integer-literal, пусть n будет буквальным без его ud-suffix. Если S содержит буквальный оператор с типом параметра unsigned long long, литерал L обрабатывается как вызов формы

operator "" X(nULL)

В противном случае S должен содержать a raw literal operator или a, literal operator template но не оба сразу. Если S содержит необработанный буквальный оператор, литерал L рассматривается как вызов формы

operator "" X("n")

В противном случае (S содержит шаблон буквального оператора) L рассматривается как вызов формы

operator "" X<'c1', 'c2', ... 'ck'>()

где n - исходная последовательность символов c1c2...ck. [ Note: Последовательность c1c2...ck может содержать только символы из базового исходного набора символов. ]end note

Если L это a user-defined-floating-literal, пусть f будет буквальным без его ud-suffix. Если S содержит буквальный оператор с типом параметра long double, литерал L обрабатывается как вызов формы

operator "" X(fL)

В противном случае S должен содержать a raw literal operator или a, literal operator template но не оба сразу. Если S содержит необработанный буквальный оператор, literal L рассматривается как вызов формы

operator "" X("f")

В противном случае (S содержит шаблон буквального оператора) L рассматривается как вызов формы

operator "" X<'c1', 'c2', ... 'ck'>()

где f - исходная последовательность символов c1c2...ck. [ Note: Последовательность c1c2...ck может содержать только символы из базового исходного набора символов. ]end note

Если L - a user-defined-string-literal, пусть str будет литералом без его, ud-suffixа пусть len будет числом кодовых единиц в str (т. Е. Его длиной, исключая завершающий нулевой символ). Литерал L рассматривается как вызов формы

operator "" X(str, len)

Если L это a user-defined-character-literal, пусть ch будет буквальным без его ud-suffix. S должен содержать literal operator , единственный параметр которого имеет тип, ch а литерал L обрабатывается как вызов формы

operator "" X(ch)

[Example:

long double operator "" _w(long double);
std::string operator "" _w(const char16_t*, std::size_t);
unsigned operator "" _w(const char*);
int main() {
  1.2_w;      // calls operator "" _­w(1.2L)
  u"one"_w;   // calls operator "" _­w(u"one", 3)
  12_w;       // calls operator "" _­w("12")
  "two"_w;    // error: no applicable literal operator
}

end example]

В translation phase 6смежные строковые литералы объединяются и user-defined-string-literals для этой цели считаются строковыми литералами. Во время конкатенации ud-suffixes удаляются и игнорируются, и происходит процесс конкатенации, как описано в [lex.string]. В конце фазы 6, если строковый литерал является результатом конкатенации, включающей хотя бы один user-defined-string-literal, все участвующие user-defined-string-literals должны иметь то же самое, ud-suffix и этот суффикс применяется к результату конкатенации.

[Example:

int main() {
  L"A" "B" "C"_x; // OK: same as L"ABC"_­x
  "P"_x "Q" "R"_y;// error: two different ud-suffixes
}

end example]