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
	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
	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
preprocessing-op-or-punc: one of
	{ 	} 	[ 	] 	# 	## 	( 	)
	<: 	:> 	<% 	%> 	%: 	%:%: 	; 	: 	...
	new 	delete 	? 	:: 	. 	.*
	+ 	- 	* 	/ 	% 	^	& 	| 	~
	! 	= 	< 	> 	+= 	-= 	*= 	/= 	%=
	^= 	&= 	|= 	<< 	>> 	>>= 	<<= 	== 	!=
	<= 	>= 	&& 	|| 	++ 	-- 	, 	->* 	->
	and 	and_eq 	bitand 	bitor 	compl 	not 	not_eq
	or 	or_eq 	xor 	xor_eq
literal:
	integer-literal
	character-literal
	floating-literal
	string-literal
	boolean-literal
	pointer-literal
	user-defined-literal
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
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
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
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.
boolean-literal:
	false
	true
pointer-literal:
	nullptr
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

A.3 Basic concepts [gram.basic]

translation-unit:
	declaration-seqopt

A.4 Expressions [gram.expr]

primary-expression:
	literal
	this
	( expression )
	id-expression
	lambda-expression
	fold-expression
id-expression:
	unqualified-id
	qualified-id
unqualified-id:
	identifier
	operator-function-id
	conversion-function-id
	literal-operator-id
	~ class-name
	~ decltype-specifier
	template-id
qualified-id:
	nested-name-specifier templateopt unqualified-id
nested-name-specifier:
	::
	type-name ::
	namespace-name ::
	decltype-specifier ::
	nested-name-specifier identifier ::
	nested-name-specifier templateopt simple-template-id ::
lambda-expression:
	lambda-introducer lambda-declaratoropt compound-statement
lambda-introducer:
	[ lambda-captureopt ]
lambda-declarator:
	( parameter-declaration-clause ) decl-specifier-seqopt
	noexcept-specifieropt attribute-specifier-seqopt trailing-return-typeopt
lambda-capture:
	capture-default
	capture-list
	capture-default , capture-list
capture-default:
	&
	=
capture-list:
	capture ...opt
	capture-list , capture ...opt
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
	+   -   *   /   %   ^   &   |   <<   >> 
	+=  -=  *=  /=  %=  ^=  &=  |=  <<=  >>=  =
	==  !=  <   >   <=  >=  &&  ||  ,    .*   ->*
postfix-expression:
	primary-expression
	postfix-expression [ expr-or-braced-init-list ]
	postfix-expression ( expression-listopt )
	simple-type-specifier ( expression-listopt )
	typename-specifier ( expression-listopt )
	simple-type-specifier braced-init-list
	typename-specifier braced-init-list
	postfix-expression . templateopt id-expression
	postfix-expression -> templateopt id-expression
	postfix-expression . pseudo-destructor-name
	postfix-expression -> pseudo-destructor-name
	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
pseudo-destructor-name:
	nested-name-specifieropt type-name ::~ type-name
	nested-name-specifier template simple-template-id ::~ type-name
	~ type-name
	~ decltype-specifier
unary-expression:
	postfix-expression
	++ cast-expression
	-- cast-expression
	unary-operator cast-expression
	sizeof unary-expression
	sizeof ( type-id )
	sizeof ... ( identifier )
	alignof ( type-id )
	noexcept-expression
	new-expression
	delete-expression
unary-operator: one of
	*  &  +  -  !  ~
new-expression:
	::opt new new-placementopt new-type-id new-initializeropt 
	::opt new new-placementopt ( type-id ) new-initializeropt
new-placement:
	( expression-list )
new-type-id:
	type-specifier-seq new-declaratoropt
new-declarator:
	ptr-operator new-declaratoropt 
	noptr-new-declarator
noptr-new-declarator:
	[ expression ] attribute-specifier-seqopt
	noptr-new-declarator [ constant-expression ] attribute-specifier-seqopt
new-initializer:
	( expression-listopt )
	braced-init-list
delete-expression:
	::opt delete cast-expression
	::opt delete [ ] cast-expression
noexcept-expression:
	noexcept ( 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
relational-expression:
	shift-expression
	relational-expression < shift-expression
	relational-expression > shift-expression
	relational-expression <= shift-expression
	relational-expression >= shift-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
throw-expression:
	throw  assignment-expressionopt
assignment-expression:
	conditional-expression
	logical-or-expression assignment-operator initializer-clause
	throw-expression
assignment-operator: one of
	=  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=
expression:
	assignment-expression
	expression , assignment-expression
constant-expression:
	conditional-expression

A.5 Statements [gram.stmt]

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

init-statement:
	expression-statement
	simple-declaration

condition:
	expression
	attribute-specifier-seqopt decl-specifier-seq declarator brace-or-equal-initializer
labeled-statement:
	attribute-specifier-seqopt identifier : statement
	attribute-specifier-seqopt case constant-expression : statement
	attribute-specifier-seqopt default : statement
expression-statement:
	expressionopt ;
compound-statement:
	{ statement-seqopt }
statement-seq:
	statement
	statement-seq statement
selection-statement:
	if constexpropt ( init-statementopt condition ) statement
	if constexpropt ( init-statementopt condition ) statement else statement
	switch ( init-statementopt condition ) statement
iteration-statement:
	while ( condition ) statement
	do statement while ( expression ) ;
	for ( init-statement conditionopt ; expressionopt ) statement
	for ( for-range-declaration : for-range-initializer ) statement
for-range-declaration:
	attribute-specifier-seqopt decl-specifier-seq declarator
	attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ]
for-range-initializer:
	expr-or-braced-init-list
jump-statement:
	break ;
	continue ;
	return expr-or-braced-init-listopt ;
	goto identifier ;
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
	linkage-specification
	namespace-definition
	empty-declaration
	attribute-declaration
block-declaration:
	simple-declaration
	asm-definition
	namespace-alias-definition
	using-declaration
	using-directive
	static_assert-declaration
	alias-declaration
	opaque-enum-declaration
nodeclspec-function-declaration:
	attribute-specifier-seqopt declarator ;
alias-declaration:
	using identifier attribute-specifier-seqopt = defining-type-id ;
simple-declaration:
	decl-specifier-seq init-declarator-listopt ;
	attribute-specifier-seq decl-specifier-seq init-declarator-list ;
	attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ 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
	inline
decl-specifier-seq:
	decl-specifier attribute-specifier-seqopt
	decl-specifier decl-specifier-seq
storage-class-specifier:
	static
	thread_local
	extern
	mutable
function-specifier:
	virtual
	explicit
typedef-name:
	identifier
type-specifier:
	simple-type-specifier
	elaborated-type-specifier
	typename-specifier
	cv-qualifier
type-specifier-seq:
	type-specifier attribute-specifier-seqopt
	type-specifier type-specifier-seq
defining-type-specifier:
	type-specifier
	class-specifier
	enum-specifier
defining-type-specifier-seq:
	defining-type-specifier attribute-specifier-seqopt
	defining-type-specifier defining-type-specifier-seq
simple-type-specifier:
	nested-name-specifieropt type-name
	nested-name-specifier template simple-template-id
	nested-name-specifieropt template-name
	char
	char16_t
	char32_t
	wchar_t
	bool
	short
	int
	long
	signed
	unsigned
	float
	double
	void
	auto
	decltype-specifier
type-name:
	class-name
	enum-name
	typedef-name
	simple-template-id
decltype-specifier:
	decltype ( expression )
	decltype ( auto )
elaborated-type-specifier:
	class-key attribute-specifier-seqopt nested-name-specifieropt identifier
	class-key simple-template-id
	class-key nested-name-specifier templateopt simple-template-id
	enum nested-name-specifieropt identifier
enum-name:
	identifier
enum-specifier:
	enum-head { enumerator-listopt }
	enum-head { enumerator-list , }
enum-head:
	enum-key attribute-specifier-seqopt enum-head-nameopt enum-baseopt
enum-head-name:
	nested-name-specifieropt identifier
opaque-enum-declaration:
	enum-key attribute-specifier-seqopt nested-name-specifieropt identifier enum-baseopt ;
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-seqopt
namespace-name:
	identifier
	namespace-alias
namespace-definition:
	named-namespace-definition
	unnamed-namespace-definition
	nested-namespace-definition
named-namespace-definition:
	inlineopt namespace attribute-specifier-seqopt identifier { namespace-body }
unnamed-namespace-definition:
	inlineopt namespace attribute-specifier-seqopt { namespace-body }
nested-namespace-definition:
	namespace enclosing-namespace-specifier :: identifier { namespace-body }
enclosing-namespace-specifier:
	identifier
	enclosing-namespace-specifier :: identifier
namespace-body:
	declaration-seqopt
namespace-alias:
	identifier
namespace-alias-definition:
	namespace identifier = qualified-namespace-specifier ;
qualified-namespace-specifier:
	nested-name-specifieropt namespace-name
using-declaration:
	using using-declarator-list ;
using-declarator-list:
	using-declarator ...opt
	using-declarator-list , using-declarator ...opt
using-declarator:
	typenameopt nested-name-specifier unqualified-id
using-directive:
	attribute-specifier-seqopt using  namespace nested-name-specifieropt namespace-name ;
asm-definition:
	attribute-specifier-seqopt asm ( string-literal ) ;
linkage-specification:
	extern string-literal { declaration-seqopt }
	extern string-literal declaration
attribute-specifier-seq:
	attribute-specifier-seqopt attribute-specifier
attribute-specifier:
	[ [ attribute-using-prefixopt attribute-list ] ]
	alignment-specifier
alignment-specifier:
	alignas ( type-id ...opt )
	alignas ( constant-expression ...opt )
attribute-using-prefix:
	using attribute-namespace :
attribute-list:
	attributeopt
	attribute-list , attributeopt
	attribute ...
	attribute-list , attribute ...
attribute:
	attribute-token attribute-argument-clauseopt
attribute-token:
	identifier
	attribute-scoped-token
attribute-scoped-token:
	attribute-namespace :: identifier
attribute-namespace:
	identifier
attribute-argument-clause:
	( balanced-token-seqopt )
balanced-token-seq:
	balanced-token
	balanced-token-seq balanced-token
balanced-token:
	( balanced-token-seqopt )
	[ balanced-token-seqopt ]
	{ balanced-token-seqopt }
	any token other than a parenthesis, a bracket, or a brace

A.7 Declarators [gram.decl]

init-declarator-list:
	init-declarator
	init-declarator-list , init-declarator
init-declarator:
	declarator initializeropt
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-seqopt
	noptr-declarator parameters-and-qualifiers
	noptr-declarator [ constant-expressionopt ] attribute-specifier-seqopt
	( ptr-declarator )
parameters-and-qualifiers:
	( parameter-declaration-clause ) cv-qualifier-seqopt
ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt
trailing-return-type:
	-> type-id
ptr-operator:
	* attribute-specifier-seqopt cv-qualifier-seqopt
	& attribute-specifier-seqopt
	&& attribute-specifier-seqopt
	nested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt
cv-qualifier-seq:
	cv-qualifier cv-qualifier-seqopt
cv-qualifier:
	const
	volatile
ref-qualifier:
	&
	&&
declarator-id:
	...opt id-expression
type-id:
	type-specifier-seq abstract-declaratoropt
defining-type-id:
	defining-type-specifier-seq abstract-declaratoropt
abstract-declarator:
	ptr-abstract-declarator
	noptr-abstract-declaratoropt parameters-and-qualifiers trailing-return-type
	abstract-pack-declarator
ptr-abstract-declarator:
	noptr-abstract-declarator
	ptr-operator ptr-abstract-declaratoropt
noptr-abstract-declarator:
	noptr-abstract-declaratoropt parameters-and-qualifiers
	noptr-abstract-declaratoropt [ constant-expressionopt ] attribute-specifier-seqopt
	( 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-expressionopt ] attribute-specifier-seqopt
	...
parameter-declaration-clause:
	parameter-declaration-listopt ...opt
	parameter-declaration-list , ...
parameter-declaration-list:
	parameter-declaration
	parameter-declaration-list , parameter-declaration
parameter-declaration:
	attribute-specifier-seqopt decl-specifier-seq declarator
	attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
	attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt
	attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt = initializer-clause
function-definition:
	attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
function-body:
	ctor-initializeropt compound-statement
	function-try-block
	= default ;
	= delete ;
initializer:
	brace-or-equal-initializer
	( expression-list )
brace-or-equal-initializer:
	= initializer-clause
	braced-init-list
initializer-clause:
	assignment-expression
	braced-init-list
initializer-list:
	initializer-clause ...opt
	initializer-list , initializer-clause ...opt
braced-init-list:
	{ initializer-list ,opt }
	{ }
expr-or-braced-init-list:
	expression
	braced-init-list

A.8 Classes [gram.class]

class-name:
	identifier
	simple-template-id
class-specifier:
	class-head { member-specificationopt }
class-head:
	class-key attribute-specifier-seqopt class-head-name class-virt-specifieropt base-clauseopt
	class-key attribute-specifier-seqopt base-clauseopt
class-head-name:
	nested-name-specifieropt class-name
class-virt-specifier:
	final
class-key:
	class
	struct
	union
member-specification:
	member-declaration member-specificationopt
	access-specifier : member-specificationopt
member-declaration:
	attribute-specifier-seqopt decl-specifier-seqopt member-declarator-listopt ;
	function-definition
	using-declaration
	static_assert-declaration
	template-declaration
	deduction-guide
	alias-declaration
	empty-declaration
member-declarator-list:
	member-declarator
	member-declarator-list , member-declarator
member-declarator:
	declarator virt-specifier-seqopt pure-specifieropt
	declarator brace-or-equal-initializeropt
	identifieropt attribute-specifier-seqopt : constant-expression
virt-specifier-seq:
	virt-specifier
	virt-specifier-seq virt-specifier
virt-specifier:
	override
	final
pure-specifier:
	= 0

A.9 Derived classes [gram.derived]

base-clause:
	: base-specifier-list
base-specifier-list:
	base-specifier ...opt
	base-specifier-list , base-specifier ...opt
base-specifier:
	attribute-specifier-seqopt class-or-decltype
	attribute-specifier-seqopt virtual access-specifieropt class-or-decltype
	attribute-specifier-seqopt access-specifier virtualopt class-or-decltype
class-or-decltype:
	nested-name-specifieropt class-name
	nested-name-specifier template simple-template-id
	decltype-specifier
access-specifier:
	private
	protected
	public

A.10 Special member functions [gram.special]

conversion-function-id:
	operator conversion-type-id
conversion-type-id:
	type-specifier-seq conversion-declaratoropt
conversion-declarator:
	ptr-operator conversion-declaratoropt
ctor-initializer:
	: mem-initializer-list
mem-initializer-list:
	mem-initializer ...opt
	mem-initializer-list , mem-initializer ...opt
mem-initializer:
	mem-initializer-id ( expression-listopt )
	mem-initializer-id braced-init-list
mem-initializer-id:
	class-or-decltype
	identifier

A.11 Overloading [gram.over]

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

A.12 Templates [gram.temp]

template-declaration:
	template < template-parameter-list > declaration
template-parameter-list:
	template-parameter
	template-parameter-list , template-parameter
template-parameter:
	type-parameter
	parameter-declaration
type-parameter:
	type-parameter-key ...opt identifieropt
	type-parameter-key identifieropt = type-id
	template < template-parameter-list > type-parameter-key ...opt identifieropt
	template < template-parameter-list > type-parameter-key identifieropt = id-expression
type-parameter-key:
	class
	typename
simple-template-id:
	template-name < template-argument-listopt >
template-id:
	simple-template-id
	operator-function-id < template-argument-listopt >
	literal-operator-id < template-argument-listopt >
template-name:
	identifier
template-argument-list:
	template-argument ...opt
	template-argument-list , template-argument ...opt
template-argument:
	constant-expression
	type-id
	id-expression
typename-specifier:
	typename nested-name-specifier identifier
	typename nested-name-specifier templateopt simple-template-id
explicit-instantiation:
	externopt template declaration
explicit-specialization:
	template < > declaration
deduction-guide:
	explicitopt template-name ( parameter-declaration-clause ) -> simple-template-id ;

A.13 Exception handling [gram.except]

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

A.14 Preprocessing directives [gram.cpp]

preprocessing-file:
	groupopt
group:
	group-part
	group group-part
group-part:
	control-line
	if-section
	text-line
	# conditionally-supported-directive
control-line:
	# include		pp-tokens new-line
	# define		identifier replacement-list new-line
	# define		identifier lparen identifier-listopt ) 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-tokensopt new-line
	# pragma		pp-tokensopt new-line
	# new-line
if-section:
	if-group elif-groupsopt else-groupopt endif-line
if-group:
	# if		constant-expression new-line groupopt
	# ifdef		identifier new-line groupopt
	# ifndef		identifier new-line groupopt
elif-groups:
	elif-group
	elif-groups elif-group
elif-group:
	# elif		constant-expression new-line groupopt
else-group:
	# else		new-line groupopt
endif-line:
	# endif		new-line
text-line:
	pp-tokensopt 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-tokensopt
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
has-include-expression:
	__has_­include ( < h-char-sequence > )
	__has_­include ( " q-char-sequence " )
	__has_­include (   string-literal  )
	__has_­include ( < h-pp-tokens     > )