______________________________________________________________________

  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