Annex A (informative) Grammar summary [gram]

This summary of C++ grammar is intended to be an aid to comprehension.
It is not an exact statement of the language.
In particular, the grammar described here accepts a superset of valid C++ constructs.
Disambiguation rules ([stmt.ambig], [dcl.spec], [class.member.lookup]) must be applied to distinguish expressions from declarations.
Further, access control, ambiguity, and type rules must be used to weed out syntactically valid but meaningless constructs.

A.1 Keywords [gram.key]

A.2 Lexical conventions [gram.lex]

hex-quad:
	hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
universal-character-name:
	\u hex-quad
	\U hex-quad hex-quad
preprocessing-token:
	header-name
	import-keyword
	module-keyword
	export-keyword
	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
token:
	identifier
	keyword
	literal
	operator-or-punctuator
header-name:
	< h-char-sequence >
	" q-char-sequence "
h-char-sequence:
	h-char
	h-char-sequence h-char
h-char:
	any member of the source character set except new-line and >
q-char-sequence:
	q-char
	q-char-sequence q-char
q-char:
	any member of the source character set except new-line and "
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 .
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
keyword:
	any identifier listed in Table tab:lex.key
	import-keyword
	module-keyword
	export-keyword
preprocessing-op-or-punc:
	preprocessing-operator
	operator-or-punctuator
preprocessing-operator: one of
	#        ##       %:       %:%:
operator-or-punctuator: one of
	{        }        [        ]        (        )
	<:       :>       <%       %>       ;        :        ...
	?        ::       .        .*       ->       ->*      ~
	!        +        -        *        /        %        ^        &        |
	=        +=       -=       *=       /=       %=       ^=       &=       |=
	==       !=       <        >        <=       >=       <=>      &&       ||
	<<       >>       <<=      >>=      ++       --       ,
	and      or       xor      not      bitand   bitor    compl
	and_eq   or_eq    xor_eq   not_eq
literal:
	integer-literal
	character-literal
	floating-point-literal
	string-literal
	boolean-literal
	pointer-literal
	user-defined-literal
integer-literal:
	binary-literal integer-suffix
	octal-literal integer-suffix
	decimal-literal integer-suffix
	hexadecimal-literal integer-suffix
binary-literal:
	0b binary-digit
	0B binary-digit
	binary-literal ' binary-digit
octal-literal:
	0
	octal-literal ' octal-digit
decimal-literal:
	nonzero-digit
	decimal-literal ' digit
hexadecimal-literal:
	hexadecimal-prefix hexadecimal-digit-sequence
binary-digit: one of
	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 ' 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-suffix 
	unsigned-suffix long-long-suffix 
	long-suffix unsigned-suffix 
	long-long-suffix unsigned-suffix
unsigned-suffix: one of
	u  U
long-suffix: one of
	l  L
long-long-suffix: one of
	ll  LL
character-literal:
	encoding-prefix ' 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 basic 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
floating-point-literal:
	decimal-floating-point-literal
	hexadecimal-floating-point-literal
decimal-floating-point-literal:
	fractional-constant exponent-part floating-point-suffix
	digit-sequence exponent-part floating-point-suffix
hexadecimal-floating-point-literal:
	hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-point-suffix
	hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-point-suffix
fractional-constant:
	digit-sequence . digit-sequence
	digit-sequence .
hexadecimal-fractional-constant:
	hexadecimal-digit-sequence . hexadecimal-digit-sequence
	hexadecimal-digit-sequence .
exponent-part:
	e sign digit-sequence
	E sign digit-sequence
binary-exponent-part:
	p sign digit-sequence
	P sign digit-sequence
sign: one of
	+  -
digit-sequence:
	digit
	digit-sequence ' digit
floating-point-suffix: one of
	f  l  F  L
string-literal:
	encoding-prefix " s-char-sequence "
	encoding-prefix R raw-string
s-char-sequence:
	s-char
	s-char-sequence s-char
s-char:
	any member of the basic source character set except the double-quote ", backslash \, or new-line character
	escape-sequence
	universal-character-name
raw-string:
	" d-char-sequence ( r-char-sequence ) d-char-sequence "
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.
boolean-literal:
	false
	true
pointer-literal:
	nullptr
user-defined-literal:
	user-defined-integer-literal
	user-defined-floating-point-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-point-literal:
	fractional-constant exponent-part 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

A.3 Basics [gram.basic]

translation-unit:
	declaration-seq
	global-module-fragment module-declaration declaration-seq private-module-fragment

A.4 Expressions [gram.expr]

primary-expression:
literal
this
( expression )
id-expression
lambda-expression
fold-expression
requires-expression
id-expression:
	unqualified-id
	qualified-id
unqualified-id:
	identifier
	operator-function-id
	conversion-function-id
	literal-operator-id
	~ type-name
	~ decltype-specifier
	template-id
qualified-id:
	nested-name-specifier template unqualified-id
nested-name-specifier:
	::
	type-name ::
	namespace-name ::
	decltype-specifier ::
	nested-name-specifier identifier ::
	nested-name-specifier template simple-template-id ::
lambda-expression:
	lambda-introducer lambda-declarator compound-statement
	lambda-introducer < template-parameter-list > requires-clause lambda-declarator compound-statement
lambda-introducer:
	[ lambda-capture ]
lambda-declarator:
	( parameter-declaration-clause ) decl-specifier-seq
		noexcept-specifier attribute-specifier-seq trailing-return-type requires-clause
lambda-capture:
	capture-default
	capture-list
	capture-default , capture-list
capture-default:
	&
	=
capture-list:
	capture
	capture-list , capture
capture:
	simple-capture
	init-capture
simple-capture:
	identifier ...
	& identifier ...
	this
	* this
init-capture:
	... identifier initializer
	& ... identifier initializer
fold-expression:
	( cast-expression fold-operator ... )
	( ... fold-operator cast-expression )
	( cast-expression fold-operator ... fold-operator cast-expression )
fold-operator: one of
	+   -   *   /   %   ^   &   |   <<   >> 
	+=  -=  *=  /=  %=  ^=  &=  |=  <<=  >>=  =
	==  !=  <   >   <=  >=  &&  ||  ,    .*   ->*
requires-expression:
	requires requirement-parameter-list requirement-body
requirement-parameter-list:
	( parameter-declaration-clause )
requirement-body:
	{ requirement-seq }
requirement-seq:
	requirement
	requirement-seq requirement
requirement:
	simple-requirement
	type-requirement
	compound-requirement
	nested-requirement
simple-requirement:
	expression ;
type-requirement:
	typename nested-name-specifier type-name ;
compound-requirement:
	{ expression } noexcept return-type-requirement ;
return-type-requirement:
	-> type-constraint
nested-requirement:
	requires constraint-expression ;
postfix-expression:
	primary-expression
	postfix-expression [ expr-or-braced-init-list ]
	postfix-expression ( expression-list )
	simple-type-specifier ( expression-list )
	typename-specifier ( expression-list )
	simple-type-specifier braced-init-list
	typename-specifier braced-init-list
	postfix-expression . template id-expression
	postfix-expression -> template id-expression
	postfix-expression ++
	postfix-expression --
	dynamic_­cast < type-id > ( expression )
	static_­cast < type-id > ( expression )
	reinterpret_­cast < type-id > ( expression )
	const_­cast < type-id > ( expression )
	typeid ( expression )
	typeid ( type-id )
expression-list:
	initializer-list
unary-expression:
	postfix-expression
	unary-operator cast-expression
	++ cast-expression
	-- cast-expression
	await-expression
	sizeof unary-expression
	sizeof ( type-id )
	sizeof ... ( identifier )
	alignof ( type-id )
	noexcept-expression
	new-expression
	delete-expression
unary-operator: one of
	*  &  +  -  !  ~
await-expression:
	co_await cast-expression
noexcept-expression:
	noexcept ( expression )
new-expression:
	:: new new-placement new-type-id new-initializer 
	:: new new-placement ( type-id ) new-initializer
new-placement:
	( expression-list )
new-type-id:
	type-specifier-seq new-declarator
new-declarator:
	ptr-operator new-declarator 
	noptr-new-declarator
noptr-new-declarator:
	[ expression ] attribute-specifier-seq
	noptr-new-declarator [ constant-expression ] attribute-specifier-seq
new-initializer:
	( expression-list )
	braced-init-list
delete-expression:
	:: delete cast-expression
	:: delete [ ] cast-expression
cast-expression:
	unary-expression
	( type-id ) cast-expression
pm-expression:
	cast-expression
	pm-expression .* cast-expression
	pm-expression ->* cast-expression
multiplicative-expression:
	pm-expression
	multiplicative-expression * pm-expression
	multiplicative-expression / pm-expression
	multiplicative-expression % pm-expression
additive-expression:
	multiplicative-expression
	additive-expression + multiplicative-expression
	additive-expression - multiplicative-expression
shift-expression:
	additive-expression
	shift-expression << additive-expression
	shift-expression >> additive-expression
compare-expression:
	shift-expression
	compare-expression <=> shift-expression
relational-expression:
	compare-expression
	relational-expression < compare-expression
	relational-expression > compare-expression
	relational-expression <= compare-expression
	relational-expression >= compare-expression
equality-expression:
	relational-expression
	equality-expression == relational-expression
	equality-expression != relational-expression
and-expression:
	equality-expression
	and-expression & equality-expression
exclusive-or-expression:
	and-expression
	exclusive-or-expression ^ and-expression
inclusive-or-expression:
	exclusive-or-expression
	inclusive-or-expression | exclusive-or-expression
logical-and-expression:
	inclusive-or-expression
	logical-and-expression && inclusive-or-expression
logical-or-expression:
	logical-and-expression
	logical-or-expression || logical-and-expression
conditional-expression:
	logical-or-expression
	logical-or-expression ? expression : assignment-expression
yield-expression:
	co_yield assignment-expression
	co_yield braced-init-list
throw-expression:
	throw  assignment-expression
assignment-expression:
	conditional-expression
	yield-expression
	throw-expression
	logical-or-expression assignment-operator initializer-clause
assignment-operator: one of
	=  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=
expression:
	assignment-expression
	expression , assignment-expression
constant-expression:
	conditional-expression

A.5 Statements [gram.stmt]

statement:
	labeled-statement
	attribute-specifier-seq expression-statement
	attribute-specifier-seq compound-statement
	attribute-specifier-seq selection-statement
	attribute-specifier-seq iteration-statement
	attribute-specifier-seq jump-statement
	declaration-statement
	attribute-specifier-seq try-block

init-statement:
	expression-statement
	simple-declaration

condition:
	expression
	attribute-specifier-seq decl-specifier-seq declarator brace-or-equal-initializer
labeled-statement:
	attribute-specifier-seq identifier : statement
	attribute-specifier-seq case constant-expression : statement
	attribute-specifier-seq default : statement
expression-statement:
	expression ;
compound-statement:
	{ statement-seq }
statement-seq:
	statement
	statement-seq statement
selection-statement:
	if constexpr ( init-statement condition ) statement
	if constexpr ( init-statement condition ) statement else statement
	switch ( init-statement condition ) statement
iteration-statement:
	while ( condition ) statement
	do statement while ( expression ) ;
	for ( init-statement condition ; expression ) statement
	for ( init-statement for-range-declaration : for-range-initializer ) statement
for-range-declaration:
	attribute-specifier-seq decl-specifier-seq declarator
	attribute-specifier-seq decl-specifier-seq ref-qualifier [ identifier-list ]
for-range-initializer:
	expr-or-braced-init-list
jump-statement:
	break ;
	continue ;
	return expr-or-braced-init-list ;
	coroutine-return-statement
	goto identifier ;
coroutine-return-statement:
	co_return expr-or-braced-init-list ;
declaration-statement:
	block-declaration

A.6 Declarations [gram.dcl]

declaration-seq:
	declaration
	declaration-seq declaration
declaration:
	block-declaration
	nodeclspec-function-declaration
	function-definition
	template-declaration
	deduction-guide
	explicit-instantiation
	explicit-specialization
	export-declaration
	linkage-specification
	namespace-definition
	empty-declaration
	attribute-declaration
	module-import-declaration
block-declaration:
	simple-declaration
	asm-declaration
	namespace-alias-definition
	using-declaration
	using-enum-declaration
	using-directive
	static_assert-declaration
	alias-declaration
	opaque-enum-declaration
nodeclspec-function-declaration:
	attribute-specifier-seq declarator ;
alias-declaration:
	using identifier attribute-specifier-seq = defining-type-id ;
simple-declaration:
	decl-specifier-seq init-declarator-list ;
	attribute-specifier-seq decl-specifier-seq init-declarator-list ;
	attribute-specifier-seq decl-specifier-seq ref-qualifier [ identifier-list ] initializer ;
static_assert-declaration:
	static_­assert ( constant-expression ) ;
	static_­assert ( constant-expression , string-literal ) ;
empty-declaration:
	;
attribute-declaration:
	attribute-specifier-seq ;
decl-specifier:
	storage-class-specifier
	defining-type-specifier
	function-specifier
	friend
	typedef
	constexpr
	consteval
	constinit
	inline
decl-specifier-seq:
	decl-specifier attribute-specifier-seq
	decl-specifier decl-specifier-seq
storage-class-specifier:
	static
	thread_­local
	extern
	mutable
function-specifier:
	virtual
	explicit-specifier
explicit-specifier:
	explicit ( constant-expression )
	explicit
typedef-name:
	identifier
	simple-template-id
type-specifier:
	simple-type-specifier
	elaborated-type-specifier
	typename-specifier
	cv-qualifier
type-specifier-seq:
	type-specifier attribute-specifier-seq
	type-specifier type-specifier-seq
defining-type-specifier:
	type-specifier
	class-specifier
	enum-specifier
defining-type-specifier-seq:
	defining-type-specifier attribute-specifier-seq
	defining-type-specifier defining-type-specifier-seq
simple-type-specifier:
	nested-name-specifier type-name
	nested-name-specifier template simple-template-id
	decltype-specifier
	placeholder-type-specifier
	nested-name-specifier template-name
	char
	char8_­t
	char16_­t
	char32_­t
	wchar_­t
	bool
	short
	int
	long
	signed
	unsigned
	float
	double
	void
type-name:
	class-name
	enum-name
	typedef-name
elaborated-type-specifier:
	class-key attribute-specifier-seq nested-name-specifier identifier
	class-key simple-template-id
	class-key nested-name-specifier template simple-template-id
	elaborated-enum-specifier
elaborated-enum-specifier:
	enum nested-name-specifier identifier
decltype-specifier:
	decltype ( expression )
placeholder-type-specifier:
	type-constraint auto
	type-constraint decltype ( auto )
init-declarator-list:
	init-declarator
	init-declarator-list , init-declarator
init-declarator:
	declarator initializer
	declarator requires-clause
declarator:
	ptr-declarator
	noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator:
	noptr-declarator
	ptr-operator ptr-declarator
noptr-declarator:
	declarator-id attribute-specifier-seq
	noptr-declarator parameters-and-qualifiers
	noptr-declarator [ constant-expression ] attribute-specifier-seq
	( ptr-declarator )
parameters-and-qualifiers:
	( parameter-declaration-clause ) cv-qualifier-seq
		ref-qualifier noexcept-specifier attribute-specifier-seq
trailing-return-type:
	-> type-id
ptr-operator:
	* attribute-specifier-seq cv-qualifier-seq
	& attribute-specifier-seq
	&& attribute-specifier-seq
	nested-name-specifier * attribute-specifier-seq cv-qualifier-seq
cv-qualifier-seq:
	cv-qualifier cv-qualifier-seq
cv-qualifier:
	const
	volatile
ref-qualifier:
	&
	&&
declarator-id:
	... id-expression
type-id:
	type-specifier-seq abstract-declarator
defining-type-id:
	defining-type-specifier-seq abstract-declarator
abstract-declarator:
	ptr-abstract-declarator
	noptr-abstract-declarator parameters-and-qualifiers trailing-return-type
	abstract-pack-declarator
ptr-abstract-declarator:
	noptr-abstract-declarator
	ptr-operator ptr-abstract-declarator
noptr-abstract-declarator:
	noptr-abstract-declarator parameters-and-qualifiers
	noptr-abstract-declarator [ constant-expression ] attribute-specifier-seq
	( ptr-abstract-declarator )
abstract-pack-declarator:
	noptr-abstract-pack-declarator
	ptr-operator abstract-pack-declarator
noptr-abstract-pack-declarator:
	noptr-abstract-pack-declarator parameters-and-qualifiers
	noptr-abstract-pack-declarator [ constant-expression ] attribute-specifier-seq
	...
parameter-declaration-clause:
	parameter-declaration-list ...
	parameter-declaration-list , ...
parameter-declaration-list:
	parameter-declaration
	parameter-declaration-list , parameter-declaration
parameter-declaration:
	attribute-specifier-seq decl-specifier-seq declarator
	attribute-specifier-seq decl-specifier-seq declarator = initializer-clause
	attribute-specifier-seq decl-specifier-seq abstract-declarator
	attribute-specifier-seq decl-specifier-seq abstract-declarator = initializer-clause
initializer:
	brace-or-equal-initializer
	( expression-list )
brace-or-equal-initializer:
	= initializer-clause
	braced-init-list
initializer-clause:
	assignment-expression
	braced-init-list
braced-init-list:
	{ initializer-list , }
	{ designated-initializer-list , }
	{ }
initializer-list:
	initializer-clause ...
	initializer-list , initializer-clause ...
designated-initializer-list:
	designated-initializer-clause
	designated-initializer-list , designated-initializer-clause
designated-initializer-clause:
	designator brace-or-equal-initializer
designator:
	. identifier
expr-or-braced-init-list:
	expression
	braced-init-list
function-definition:
	attribute-specifier-seq decl-specifier-seq declarator virt-specifier-seq function-body
	attribute-specifier-seq decl-specifier-seq declarator requires-clause function-body
function-body:
	ctor-initializer compound-statement
	function-try-block
	= default ;
	= delete ;
enum-name:
	identifier
enum-specifier:
	enum-head { enumerator-list }
	enum-head { enumerator-list , }
enum-head:
	enum-key attribute-specifier-seq enum-head-name enum-base
enum-head-name:
	nested-name-specifier identifier
opaque-enum-declaration:
	enum-key attribute-specifier-seq enum-head-name enum-base ;
enum-key:
	enum
	enum class
	enum struct
enum-base:
	: type-specifier-seq
enumerator-list:
	enumerator-definition
	enumerator-list , enumerator-definition
enumerator-definition:
	enumerator
	enumerator = constant-expression
enumerator:
	identifier attribute-specifier-seq
using-enum-declaration:
	using elaborated-enum-specifier ;
namespace-name:
	identifier
	namespace-alias
namespace-definition:
	named-namespace-definition
	unnamed-namespace-definition
	nested-namespace-definition
named-namespace-definition:
	inline namespace attribute-specifier-seq identifier { namespace-body }
unnamed-namespace-definition:
	inline namespace attribute-specifier-seq { namespace-body }
nested-namespace-definition:
	namespace enclosing-namespace-specifier :: inline identifier { namespace-body }
enclosing-namespace-specifier:
	identifier
	enclosing-namespace-specifier :: inline identifier
namespace-body:
	declaration-seq
namespace-alias:
	identifier
namespace-alias-definition:
	namespace identifier = qualified-namespace-specifier ;
qualified-namespace-specifier:
	nested-name-specifier namespace-name
using-directive:
	attribute-specifier-seq using namespace nested-name-specifier namespace-name ;
using-declaration:
	using using-declarator-list ;
using-declarator-list:
	using-declarator ...
	using-declarator-list , using-declarator ...
using-declarator:
	typename nested-name-specifier unqualified-id
asm-declaration:
	attribute-specifier-seq asm ( string-literal ) ;
linkage-specification:
	extern string-literal { declaration-seq }
	extern string-literal declaration
attribute-specifier-seq:
	attribute-specifier-seq attribute-specifier
attribute-specifier:
	[ [ attribute-using-prefix attribute-list ] ]
	alignment-specifier
alignment-specifier:
	alignas ( type-id ... )
	alignas ( constant-expression ... )
attribute-using-prefix:
	using attribute-namespace :
attribute-list:
	attribute
	attribute-list , attribute
	attribute ...
	attribute-list , attribute ...
attribute:
	attribute-token attribute-argument-clause
attribute-token:
	identifier
	attribute-scoped-token
attribute-scoped-token:
	attribute-namespace :: identifier
attribute-namespace:
	identifier
attribute-argument-clause:
	( balanced-token-seq )
balanced-token-seq:
	balanced-token
	balanced-token-seq balanced-token
balanced-token:
	( balanced-token-seq )
	[ balanced-token-seq ]
	{ balanced-token-seq }
	any token other than a parenthesis, a bracket, or a brace

A.7 Modules [gram.module]

module-declaration:
	export-keyword module-keyword module-name module-partition attribute-specifier-seq ;
module-name:
	module-name-qualifier identifier
module-partition:
	: module-name-qualifier identifier
module-name-qualifier:
	identifier .
	module-name-qualifier identifier .
export-declaration:
	export declaration
	export { declaration-seq }
	export-keyword module-import-declaration
module-import-declaration:
	import-keyword module-name attribute-specifier-seq ;
	import-keyword module-partition attribute-specifier-seq ;
	import-keyword header-name attribute-specifier-seq ;
global-module-fragment:
	module-keyword ; declaration-seq
private-module-fragment:
	module-keyword : private ; declaration-seq

A.8 Classes [gram.class]

class-name:
	identifier
	simple-template-id
class-specifier:
	class-head { member-specification }
class-head:
	class-key attribute-specifier-seq class-head-name class-virt-specifier base-clause
	class-key attribute-specifier-seq base-clause
class-head-name:
	nested-name-specifier class-name
class-virt-specifier:
	final
class-key:
	class
	struct
	union
member-specification:
	member-declaration member-specification
	access-specifier : member-specification
member-declaration:
	attribute-specifier-seq decl-specifier-seq member-declarator-list ;
	function-definition
	using-declaration
	using-enum-declaration
	static_assert-declaration
	template-declaration
	explicit-specialization
	deduction-guide
	alias-declaration
	opaque-enum-declaration
	empty-declaration
member-declarator-list:
	member-declarator
	member-declarator-list , member-declarator
member-declarator:
	declarator virt-specifier-seq pure-specifier
	declarator requires-clause
	declarator brace-or-equal-initializer
	identifier attribute-specifier-seq : constant-expression brace-or-equal-initializer
virt-specifier-seq:
	virt-specifier
	virt-specifier-seq virt-specifier
virt-specifier:
	override
	final
pure-specifier:
	= 0
conversion-function-id:
	operator conversion-type-id
conversion-type-id:
	type-specifier-seq conversion-declarator
conversion-declarator:
	ptr-operator conversion-declarator
base-clause:
	: base-specifier-list
base-specifier-list:
	base-specifier ...
	base-specifier-list , base-specifier ...
base-specifier:
	attribute-specifier-seq class-or-decltype
	attribute-specifier-seq virtual access-specifier class-or-decltype
	attribute-specifier-seq access-specifier virtual class-or-decltype
class-or-decltype:
	nested-name-specifier type-name
	nested-name-specifier template simple-template-id
	decltype-specifier
access-specifier:
	private
	protected
	public
ctor-initializer:
	: mem-initializer-list
mem-initializer-list:
	mem-initializer ...
	mem-initializer-list , mem-initializer ...
mem-initializer:
	mem-initializer-id ( expression-list )
	mem-initializer-id braced-init-list
mem-initializer-id:
	class-or-decltype
	identifier

A.9 Overloading [gram.over]

operator-function-id:
	operator operator
operator: one of
	new      delete   new[]    delete[] co_await ()        []        ->       ->*
	~        !        +        -        *        /        %        ^        &
	|        =        +=       -=       *=       /=       %=       ^=       &=
	|=       ==       !=       <        >        <=       >=       <=>      &&
	||       <<       >>       <<=      >>=      ++       --       ,
literal-operator-id:
	operator string-literal identifier
	operator user-defined-string-literal

A.10 Templates [gram.temp]

template-declaration:
	template-head declaration
	template-head concept-definition
template-head:
	template < template-parameter-list > requires-clause
template-parameter-list:
	template-parameter
	template-parameter-list , template-parameter
requires-clause:
	requires constraint-logical-or-expression
constraint-logical-or-expression:
	constraint-logical-and-expression
	constraint-logical-or-expression || constraint-logical-and-expression
constraint-logical-and-expression:
	primary-expression
	constraint-logical-and-expression && primary-expression
template-parameter:
	type-parameter
	parameter-declaration
type-parameter:
	type-parameter-key ... identifier
	type-parameter-key identifier = type-id
	type-constraint ... identifier
	type-constraint identifier = type-id
	template-head type-parameter-key ... identifier
	template-head type-parameter-key identifier = id-expression
type-parameter-key:
	class
	typename
type-constraint:
	nested-name-specifier concept-name
	nested-name-specifier concept-name < template-argument-list >
simple-template-id:
	template-name < template-argument-list >
template-id:
	simple-template-id
	operator-function-id < template-argument-list >
	literal-operator-id < template-argument-list >
template-name:
	identifier
template-argument-list:
	template-argument ...
	template-argument-list , template-argument ...
template-argument:
	constant-expression
	type-id
	id-expression
constraint-expression:
	logical-or-expression
deduction-guide:
	explicit-specifier template-name ( parameter-declaration-clause ) -> simple-template-id ;
concept-definition:
	concept concept-name = constraint-expression ;
concept-name:
	identifier
typename-specifier:
	typename nested-name-specifier identifier
	typename nested-name-specifier template simple-template-id
explicit-instantiation:
	extern template declaration
explicit-specialization:
	template < > declaration

A.11 Exception handling [gram.except]

try-block:
	try compound-statement handler-seq
function-try-block:
	try ctor-initializer compound-statement handler-seq
handler-seq:
	handler handler-seq
handler:
	catch ( exception-declaration ) compound-statement
exception-declaration:
	attribute-specifier-seq type-specifier-seq declarator
	attribute-specifier-seq type-specifier-seq abstract-declarator
	...
noexcept-specifier:
	noexcept ( constant-expression )
	noexcept

A.12 Preprocessing directives [gram.cpp]

preprocessing-file:
	group
	module-file
module-file:
	pp-global-module-fragment pp-module group pp-private-module-fragment
pp-global-module-fragment:
	module ; new-line group
pp-private-module-fragment:
	module : private ; new-line group
group:
	group-part
	group group-part
group-part:
	control-line
	if-section
	text-line
	# conditionally-supported-directive
control-line:
	# include pp-tokens new-line
	pp-import
	# define  identifier replacement-list new-line
	# define  identifier lparen identifier-list ) replacement-list new-line
	# define  identifier lparen ... ) replacement-list new-line
	# define  identifier lparen identifier-list , ... ) replacement-list new-line
	# undef   identifier new-line
	# line    pp-tokens new-line
	# error   pp-tokens new-line
	# pragma  pp-tokens new-line
	# new-line
if-section:
	if-group elif-groups else-group endif-line
if-group:
	# if      constant-expression new-line group
	# ifdef   identifier new-line group
	# ifndef  identifier new-line group
elif-groups:
	elif-group
	elif-groups elif-group
elif-group:
	# elif    constant-expression new-line group
else-group:
	# else    new-line group
endif-line:
	# endif   new-line
text-line:
	pp-tokens new-line
conditionally-supported-directive:
	pp-tokens new-line
lparen:
	a ( character not immediately preceded by white-space
identifier-list:
	identifier
	identifier-list , identifier
replacement-list:
	pp-tokens
pp-tokens:
	preprocessing-token
	pp-tokens preprocessing-token
new-line:
	the new-line character
defined-macro-expression:
	defined identifier
	defined ( identifier )
h-preprocessing-token:
	any preprocessing-token other than >
h-pp-tokens:
	h-preprocessing-token
	h-pp-tokens h-preprocessing-token
header-name-tokens:
	string-literal
	< h-pp-tokens >
has-include-expression:
	_­_­has_­include ( header-name )
	_­_­has_­include ( header-name-tokens )
has-attribute-expression:
	_­_­has_­cpp_­attribute ( pp-tokens )
pp-module:
	export module pp-tokens ; new-line
pp-import:
	export import header-name pp-tokens ; new-line
	export import header-name-tokens pp-tokens ; new-line
	export import pp-tokens ; new-line
va-opt-replacement:
	__VA_­OPT__ ( pp-tokens )