______________________________________________________________________ Annex 0 (informative) Grammar summary [gram] ______________________________________________________________________ 1 This summary of C++ syntax 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. Fur- ther, access control, ambiguity, and type rules must be used to weed out syntactically valid but meaningless constructs. 1.1 Keywords [gram.key] 1 New context-dependent keywords are introduced into a program by type- def (_dcl.typedef_), namespace (_namespace.def_), class (_class_), enumeration (_dcl.enum_), and template (_temp_) declarations. typedef-name: identifier namespace-name: original-namespace-name namespace-alias original-namespace-name: identifier namespace-alias: identifier class-name: identifier template-id enum-name: identifier template-name: identifier Note that a typedef-name naming a class is also a class-name (_class.name_). 1.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 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 nondigit pp-number e sign pp-number E sign pp-number . identifier: nondigit identifier nondigit identifier digit nondigit: one of universal-character-name _ 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 integer-literal: decimal-literal integer-suffixopt octal-literal integer-suffixopt hexadecimal-literal integer-suffixopt decimal-literal: nonzero-digit decimal-literal digit octal-literal: 0 octal-literal octal-digit hexadecimal-literal: 0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-literal hexadecimal-digit nonzero-digit: one of 1 2 3 4 5 6 7 8 9 octal-digit: one of 0 1 2 3 4 5 6 7 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 long-suffix unsigned-suffixopt unsigned-suffix: one of u U long-suffix: one of l L character-literal: 'c-char-sequence' L'c-char-sequence' 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: fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt fractional-constant: digit-sequenceopt . digit-sequence digit-sequence . exponent-part: e signopt digit-sequence E signopt digit-sequence sign: one of + - digit-sequence: digit digit-sequence digit floating-suffix: one of f l F L string-literal: "s-char-sequenceopt" L"s-char-sequenceopt" 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 boolean-literal: false true 1.3 Basic concepts [gram.basic] translation-unit: declaration-seqopt 1.4 Expressions [gram.expr] primary-expression: literal this :: identifier :: operator-function-id :: qualified-id ( expression ) id-expression id-expression: unqualified-id qualified-id id-expression: unqualified-id qualified-id unqualified-id: identifier operator-function-id conversion-function-id ~ class-name template-id qualified-id: nested-name-specifier templateopt unqualified-id nested-name-specifier: class-or-namespace-name :: nested-name-specifieropt class-or-namespace-name: class-name namespace-name postfix-expression: primary-expression postfix-expression [ expression ] postfix-expression ( expression-listopt ) simple-type-specifier ( expression-listopt ) postfix-expression . templateopt ::opt id-expression postfix-expression -> templateopt ::opt 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: assignment-expression expression-list , assignment-expression pseudo-destructor-name: ::opt nested-name-specifieropt type-name :: ~ type-name ::opt nested-name-specifieropt ~ type-name unary-expression: postfix-expression ++ cast-expression -- cast-expression unary-operator cast-expression sizeof unary-expression sizeof ( type-id ) 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 direct-new-declarator direct-new-declarator: [ expression ] direct-new-declarator [ constant-expression ] new-initializer: ( expression-listopt ) delete-expression: ::opt delete cast-expression ::opt 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 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 assignment-expression: conditional-expression logical-or-expression assignment-operator assignment-expression throw-expression assignment-operator: one of = *= /= %= += -= >>= <<= &= ^= |= expression: assignment-expression expression , assignment-expression constant-expression: conditional-expression 1.5 Statements [gram.stmt.stmt] statement: labeled-statement expression-statement compound-statement selection-statement iteration-statement jump-statement declaration-statement try-block labeled-statement: identifier : statement case constant-expression : statement default : statement expression-statement: expressionopt ; compound-statement: { statement-seqopt } statement-seq: statement statement-seq statement selection-statement: if ( condition ) statement if ( condition ) statement else statement switch ( condition ) statement condition: expression type-specifier-seq declarator = assignment-expression iteration-statement: while ( condition ) statement do statement while ( expression ) ; for ( for-init-statement conditionopt ; expressionopt ) statement for-init-statement: expression-statement simple-declaration jump-statement: break ; continue ; return expressionopt ; goto identifier ; declaration-statement: block-declaration 1.6 Declarations [gram.dcl.dcl] declaration-seq: declaration declaration-seq declaration declaration: block-declaration function-definition template-declaration explicit-instantiation explicit-specialization linkage-specification namespace-definition block-declaration: simple-declaration asm-definition namespace-alias-definition using-declaration using-directive simple-declaration: decl-specifier-seqopt init-declarator-listopt ; decl-specifier: storage-class-specifier type-specifier function-specifier friend typedef decl-specifier-seq: decl-specifier-seqopt decl-specifier storage-class-specifier: auto register static extern mutable function-specifier: inline virtual explicit typedef-name: identifier type-specifier: simple-type-specifier class-specifier enum-specifier elaborated-type-specifier cv-qualifier simple-type-specifier: ::opt nested-name-specifieropt type-name char wchar_t bool short int long signed unsigned float double void type-name: class-name enum-name typedef-name elaborated-type-specifier: class-key ::opt nested-name-specifieropt identifier enum ::opt nested-name-specifieropt identifier typename ::opt nested-name-specifier identifier typename ::opt nested-name-specifier identifier < template-argument-list > enum-name: identifier enum-specifier: enum identifieropt { enumerator-listopt } enumerator-list: enumerator-definition enumerator-list , enumerator-definition enumerator-definition: enumerator enumerator = constant-expression enumerator: identifier namespace-name: original-namespace-name namespace-alias original-namespace-name: identifier namespace-definition: named-namespace-definition unnamed-namespace-definition named-namespace-definition: original-namespace-definition extension-namespace-definition original-namespace-definition: namespace identifier { namespace-body } extension-namespace-definition: namespace original-namespace-name { namespace-body } unnamed-namespace-definition: namespace { namespace-body } namespace-body: declaration-seqopt namespace-alias: identifier namespace-alias-definition: namespace identifier = qualified-namespace-specifier ; qualified-namespace-specifier: ::opt nested-name-specifieropt namespace-name using-declaration: using typenameopt ::opt nested-name-specifier unqualified-id ; using :: unqualified-id ; using-directive: using namespace ::opt nested-name-specifieropt namespace-name ; asm-definition: asm ( string-literal ) ; linkage-specification: extern string-literal { declaration-seqopt } extern string-literal declaration 1.7 Declarators [gram.dcl.decl] init-declarator-list: init-declarator init-declarator-list , init-declarator init-declarator: declarator initializeropt declarator: direct-declarator ptr-operator declarator direct-declarator: declarator-id direct-declarator ( parameter-declaration-clause ) cv-qualifier-seqopt exception-specificationopt direct-declarator [ constant-expressionopt ] ( declarator ) ptr-operator: * cv-qualifier-seqopt & ::opt nested-name-specifier * cv-qualifier-seqopt cv-qualifier-seq: cv-qualifier cv-qualifier-seqopt cv-qualifier: const volatile declarator-id: ::opt id-expression ::opt nested-name-specifieropt type-name type-id: type-specifier-seq abstract-declaratoropt type-specifier-seq: type-specifier type-specifier-seqopt abstract-declarator: ptr-operator abstract-declaratoropt direct-abstract-declarator direct-abstract-declarator: direct-abstract-declaratoropt ( parameter-declaration-clause ) cv-qualifier-seqopt exception-specificationopt direct-abstract-declaratoropt [ constant-expressionopt ] ( abstract-declarator ) parameter-declaration-clause: parameter-declaration-listopt ...opt parameter-declaration-list , ... parameter-declaration-list: parameter-declaration parameter-declaration-list , parameter-declaration parameter-declaration: decl-specifier-seq declarator decl-specifier-seq declarator = assignment-expression decl-specifier-seq abstract-declaratoropt decl-specifier-seq abstract-declaratoropt = assignment-expression function-definition: decl-specifier-seqopt declarator ctor-initializeropt function-body decl-specifier-seqopt declarator function-try-block function-body: compound-statement initializer: = initializer-clause ( expression-list ) initializer-clause: assignment-expression { initializer-list ,opt } { } initializer-list: initializer-clause initializer-list , initializer-clause 1.8 Classes [gram.class] class-name: identifier template-id class-specifier: class-head { member-specificationopt } class-head: class-key identifieropt base-clauseopt class-key nested-name-specifier identifier base-clauseopt class-key: class struct union member-specification: member-declaration member-specificationopt access-specifier : member-specificationopt member-declaration: decl-specifier-seqopt member-declarator-listopt ; function-definition ;opt qualified-id ; using-declaration template-declaration member-declarator-list: member-declarator member-declarator-list , member-declarator member-declarator: declarator pure-specifieropt declarator constant-initializeropt identifieropt : constant-expression pure-specifier: = 0 constant-initializer: = constant-expression 1.9 Derived classes [gram.class.derived] base-clause: : base-specifier-list base-specifier-list: base-specifier base-specifier-list , base-specifier base-specifier: ::opt nested-name-specifieropt class-name virtual access-specifieropt ::opt nested-name-specifieropt class-name access-specifier virtualopt ::opt nested-name-specifieropt class-name access-specifier: private protected public 1.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 mem-initializer , mem-initializer-list mem-initializer: mem-initializer-id ( expression-listopt ) mem-initializer-id: ::opt nested-name-specifieropt class-name identifier 1.11 Overloading [gram.over] operator-function-id: operator operator operator: one of new delete new[] delete[] + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- , ->* -> () [] 1.12 Templates [gram.temp] template-declaration: exportopt template < template-parameter-list > declaration template-parameter-list: template-parameter template-parameter-list , template-parameter template-parameter: type-parameter parameter-declaration type-parameter: class identifieropt class identifieropt = type-id typename identifieropt typename identifieropt = type-id template < template-parameter-list > class identifieropt template < template-parameter-list > class identifieropt = template-name template-id: template-name < template-argument-list > template-name: identifier template-argument-list: template-argument template-argument-list , template-argument template-argument: assignment-expression type-id template-name explicit-instantiation: template declaration explicit-specialization: template < > declaration 1.13 Exception handling [gram.except] try-block: try compound-statement handler-seq function-try-block: try ctor-initializeropt function-body handler-seq handler-seq: handler handler-seqopt handler: catch ( exception-declaration ) compound-statement exception-declaration: type-specifier-seq declarator type-specifier-seq abstract-declarator type-specifier-seq ... throw-expression: throw assignment-expressionopt exception-specification: throw ( type-id-listopt ) type-id-list: type-id type-id-list , type-id 1.14 Preprocessing directives [gram.cpp] preprocessing-file: groupopt group: group-part group group-part group-part: pp-tokensopt new-line if-section control-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 control-line: # include pp-tokens new-line # define identifier replacement-list new-line # define identifier lparen identifier-listopt ) 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 lparen: the left-parenthesis character without preceding white-space replacement-list: pp-tokensopt pp-tokens: preprocessing-token pp-tokens preprocessing-token new-line: the new-line character