      ______________________________________________________________________

      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