[CSUSB] >> [CompSci] >> [Dick Botting] >> [C++] >> syntax
[Index] || [Source] Mon May 26 09:24:35 PDT 2003

Contents (index)


    Introduction

    This is a fast translation of the ASCII version of the draft into MATHS - a readable and writable formal language. I've done this (1)to show that it can be done, (2) show that the result is shorter than the original, and (3) see what I can learn about describing complex things like C++.

    It based on the HTML version of the December 1997 draft standard: [ c++std ] See [ Syntax in index ] for pointers to official grammars and older versions.

    I may have missed some syntax definitions and almost certainly failed to distinguish defined nonterminals from terminal symbols. Please send Email to rbotting@wiley.csusb.edu to help me correct any errors.

    Metalanguage


      This uses the standard XBNF syntax conventions of MATHS with "|" indicating or and the original BNF symbol for a definition:
    1. defined_term::=definition_of_that_term. Plus
    2. #(X)::=A sequence of zero or more X'x.
    3. O(X)::=An optional X.
    4. N(X)::=One or more X's.
    5. L(X)::=A comma separated list of X's.
    6. X^n::=a sequence of n X's.
    7. A~B::=Any A that is not a B. [ math.syntax.html ]

    The following are used in the C++ syntax only:

  1. Opt(X)::=O(X), an optional X.
  2. Seq(X)::=N(X), a sequence of one or more X's.

    Syntax of C++ as per Draft ANSI/ISO Standard December 1997

    Characters

  3. characters::=ASCII.char ~ "$",
  4. ASCII::=see following [ comp.text.ASCII.html ]
  5. backslash::=ASCII.backslash. [ backslash in comp.text.ASCII ]
  6. hash::=ASCII.sharp [ sharp in comp.text.ASCII ]
  7. comma::=ASCII.comma, [ comma in comp.text.ASCII ]
  8. quotes::=ASCII.double_quote, [ quotation in comp.text.ASCII ]
  9. quote::=ASCII.single_quote, [ apostrophe in comp.text.ASCII ]
  10. new_line::=the new_line character. [ EOLN in comp.text.ASCII ]
  11. double_colon::=ASCII.colon ASCII.colon, [ colon in comp.text.ASCII ]
  12. left_paren::="(".
  13. right_paren::=")".
  14. left_brace::="{".
  15. right_brace::="}".
  16. left_bracket::="[".
  17. right_bracket::="]".

    Lexicon

  18. typeid::lexeme="typeid".

    More to be worked out...

    Lexemes

  19. hex_quad::= hexadecimal_digit^4.

  20. universal_character_name::= backslash "u" hex_quad | backslash "U" hex_quad^2.

  21. 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.

  22. token::= identifier | keyword | literal | operator | punctuator.

  23. keyword::= predefined_keyword | introduced_keyword. New context-dependent keywords are introduced by type_def, namespace, class, enumeration, and template definitions.

  24. header_name::= "<" h_char_sequence">" | quotes q_char_sequence quotes.

  25. h_char_sequence::=Seq(characters~(">" | new_line)).

  26. q_char_sequence::=Seq(characters~(quotes | new_line)).

  27. pp_number::= (digit | "." digit ) #( digit | nondigit | ("e" | "E" ) sign | "."), note that this is the lexical form of a number as seen by the preprocessor not the correct syntax for numerical literals as seen by the C++ compiler. For this see literal below.

  28. identifier::= nondigit #( nondigit | digit).

  29. nondigit::= universal_character_name | ASCII.letter | ASCII.underscore.

  30. digit::= "0".."9".

  31. preprocessing_op_or_punc::= left_brace | right_brace | left_bracket | right_bracket |hash| hash^2 | left_paren | right_paren | "<:" | ":>" | "<%" | "%>" | "%:" | "%:%:" | ";" | ":" | "..." | "new" | "delete" "?" | double_colon | "." | ".*" | "+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~" | "!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|="| "<<" | ">>" | ">>=" | "<<=" | "==" | "!=" | "<=" | ">=" | "&&" | "||" | "++" | "--" | "comma" | "->*" | "->" | "and" | "and_eq" | "bitand" | "bitor" | "compl" | "not" | "not_eq" | "or"| "or_eq" | "xor" | "xor_eq".

  32. literal::= integer_literal | character_literal | floating_literal | string_literal | boolean_literal.

  33. integer_literal::= decimal_literal Opt( integer_suffix ) | octal_literal Opt( integer_suffix ) | hexadecimal_literal Opt( integer_suffix ).

  34. decimal_literal::= nonzero_digit #(digit).

  35. octal_literal::= "0" #(octal_digit).

  36. hexadecimal_literal::=( "0x" | "0X") #(hexadecimal_digit).

  37. nonzero_digit::= digit~"0".

  38. octal_digit::= "0".."7".

  39. hexadecimal_digit::= "0".."9" | "a".."f" | "A".."F".

  40. integer_suffix::= unsigned_suffix Opt( long_suffix ) | long_suffix Opt( unsigned_suffix ).

  41. unsigned_suffix::= "u" | "U".

  42. long_suffix::= "l" | "L".

  43. character_literal::= quote Seq(c_char) quote | "L" quote Seq(c_char) quote .

  44. c_char::=characters~( quote | backslash | new_line ) | escape_sequence | universal_character_name.

  45. escape_sequence::= simple_escape_sequence |octal_escape_sequence | hexadecimal_escape_sequence.

  46. simple_escape_sequence::= backslash ( quote | quotes | "?" | backslash | "a" | "b" | "f" |"n" | "r" | "t" | "v" ).

  47. octal_escape_sequence::= backslash (octal_digit | octal_digit^2 | octal_digit^3).

  48. hexadecimal_escape_sequence::= backslash "x" Seq(hexadecimal_digit).

  49. floating_literal::= fractional_constant Opt( exponent_part ) Opt( floating_suffix ) | Seq(digit) exponent_part Opt( floating_suffix ).

  50. fractional_constant::= Opt( Seq(digit) ) "." Seq(digit) | Seq(digit) ".".

  51. exponent_part::= "e" Opt( sign ) Seq(digit) | "E" Opt( sign ) Seq(digit).

  52. sign::= plus | minus.

  53. floating_suffix::= "f" | "l" | "F" | "L".

  54. string_literal::= Opt("L") quotes Opt( Seq(s_char) ) quotes.

  55. s_char::=(characters ~ ( quotes | backslash | new_line ))| escape_sequence | universal_character_name.

  56. boolean_literal::= "false" | "true".

    Basic Ideas

  57. translation_unit::= Opt( declaration_seq ).

    Names

  58. id_expression::= unqualified_id | qualified_id.

  59. unqualified_id::= identifier | operator_function_id | conversion_function_id | "~" class_name | template_id.

  60. qualified_id::= nested_name_specifier Opt( "template" ) unqualified_id.

  61. nested_name_specifier::= class_or_namespace_name double_colon Opt( nested_name_specifier ).

  62. class_or_namespace_name::= class_name | namespace_name.

    Expressions

  63. primary_expression::= literal | "this" | double_colon identifier | double_colon operator_function_id | double_colon qualified_id | "(" expression ")" | id_expression.

  64. postfix_expression::=( primary_expression | simple_type_specifier "(" Opt( expression_list ) ")" | cast "<" type_id ">" "(" expression ")" | "typeid" "(" (expression | type_id ")") ) postfix_operations.

  65. postfix_operations::= #( "[" expression "]" | "(" Opt( expression_list ) ")" | "." Opt( "template" ) Opt(double_colon) id_expression | "->" Opt( "template" ) Opt(double_colon) id_expression | "." pseudo_destructor_name | "->" pseudo_destructor_name | "++" | "--").

  66. expression_list::= assignment_expression | expression_list comma assignment_expression.

  67. cast::="dynamic_cast" | "static_cast" | "const_cast" | "reinterpret_cast".

  68. pseudo_destructor_name::= Opt(double_colon) Opt( nested_name_specifier ) type_name double_colon "~" type_name | Opt(double_colon) Opt( nested_name_specifier ) "~" type_name.

  69. unary_expression::= postfix_expression | "++" cast_expression | "--" cast_expression | unary_operator cast_expression | "sizeof" unary_expression | "sizeof" "(" type_id ")" | new_expression | delete_expression.

  70. unary_operator::= "|" | "*" | "&" | "+" | "-" | "!" | "~".

  71. new_expression::= Opt(double_colon) "new" Opt( new_placement ) ( new_type_id | "(" type_id ")" ) Opt( new_initializer ).

  72. new_placement::= left_paren expression_list right_paren.

  73. new_type_id::= type_specifier_seq Opt( new_declarator ).

  74. new_declarator::= ptr_operator Opt( new_declarator ) | direct_new_declarator.

  75. direct_new_declarator::= Seq(left_bracket expression right_bracket).

  76. new_initializer::= left_paren Opt( expression_list ) right_paren.

  77. delete_expression::= Opt(double_colon) "delete" Opt( "[]" ) cast_expression.

  78. cast_expression::= unary_expression | left_paren type_id right_paren cast_expression.

  79. pm_expression::= #( cast_expression ( ".*" | "->*" )) cast_expression.

  80. For Expr, Op, infix(Expr, Op)::= Expr #(Op Expr).

  81. multiplicative_expression::=infix(pm_expression, ("*" | "/" | "%" )).

  82. additive_expression::=infix( multiplicative_expression, ("+" | "-")).

  83. shift_expression::=infix( additive_expression, ("<<" | ">>" )).

  84. relational_expression::= infix( shift_expression, ("<" | ">" |"<=" | ">=" )).

  85. equality_expression::= infix( relational_expression, ("==" | "!=")).

  86. and_expression::= infix( equality_expression, "&" ).

  87. exclusive_or_expression::= infix( and_expression, "^").

  88. inclusive_or_expression::= infix( exclusive_or_expression , "|").

  89. logical_and_expression::= infix( inclusive_or_expression, "&&" ).

  90. logical_or_expression::= infix( logical_and_expression, "||" ).

  91. conditional_expression::= logical_or_expression | logical_or_expression "?" expression ":" assignment_expression.

  92. assignment_expression::= conditional_expression | logical_or_expression assignment_operator assignment_expression | throw_expression.

  93. assignment_operator::= "|" | "=" | "*=" | "/= %=" | " +=" | "-=" | ">>=" | "<<=" | "&=" | "^=" | "|=".

  94. expression::= assignment_expression | expression comma assignment_expression.

  95. constant_expression::=conditional_expression.

    Statements

  96. statement::= labeled_statement | expression_statement | compound_statement | selection_statement | iteration_statement | jump_statement | declaration_statement | try_block.

  97. labeled_statement::= identifier ":" statement | "case" constant_expression ":" statement | "default" ":" statement.

  98. expression_statement::= Opt( expression ) ";" .

  99. compound_statement::= left_brace Opt( statement_seq ) right_brace.

  100. statement_seq::= Seq( statement).

  101. selection_statement::= "if" "(" condition ")" statement | "if" "(" condition ")" statement else statement | switch "(" condition ")" statement.

  102. condition::= expression | type_specifier_seq declarator "=" assignment_expression.

  103. iteration_statement::= "while" "(" condition ")" statement | "do" statement "while" "(" expression ")" ";" | "for" "(" for_init_statement Opt( condition ) ";" Opt( expression ) ")" statement.

  104. for_init_statement::= expression_statement | simple_declaration.

  105. jump_statement::= "break" ";" | "continue" ";" | "return" Opt( expression ) ";" | "goto" identifier ";" .

  106. declaration_statement::= block_declaration.

  107. declaration_seq::= Seq( declaration ).

  108. declaration::= block_declaration | function_definition | template_declaration | explicit_instantiation | explicit_specialization | linkage_specification | namespace_definition.

  109. block_declaration::= simple_declaration | asm_definition | namespace_alias_definition | using_declaration | using_directive.

  110. simple_declaration::= Opt( decl_specifier_seq ) Opt( init_declarator_list ) ";" .

  111. decl_specifier::= storage_class_specifier | type_specifier | function_specifier | "friend" | "typedef".

  112. decl_specifier_seq::= Opt( decl_specifier_seq ) decl_specifier.

  113. storage_class_specifier::= "auto" | "register" | "static" | "extern" | "mutable".

  114. function_specifier::= "inline" | "virtual" | "explicit".

  115. typedef_name::= identifier.

  116. type_specifier::= simple_type_specifier | class_specifier | enum_specifier | elaborated_type_specifier | cv_qualifier.

  117. simple_type_specifier::= Opt(double_colon ) Opt( nested_name_specifier ) type_name | "char" | "wchar_t" | "bool" | "short" | "int" | "long" | "signed" | "unsigned" | "float" | "double" | "void".

  118. type_name::= class_name | enum_name | typedef_name.

  119. elaborated_type_specifier::= class_key Opt(double_colon) Opt( nested_name_specifier ) identifier | "enum" Opt(double_colon) Opt( nested_name_specifier ) identifier | typename Opt(double_colon) nested_name_specifier identifier | typename Opt(double_colon) nested_name_specifier identifier "<" template_argument_list ">".

    Enums

  120. enum_name::= identifier.

  121. enum_specifier::= "enum" Opt( identifier ) left_brace Opt( enumerator_list ) right_brace.

  122. enumerator_list::= enumerator_definition | enumerator_list comma enumerator_definition.

  123. enumerator_definition::= enumerator | enumerator "=" constant_expression.

  124. enumerator::= identifier.

    Namespaces

  125. namespace_name::= original_namespace_name | namespace_alias.

  126. original_namespace_name::= identifier.

  127. namespace_definition::= named_namespace_definition | unnamed_namespace_definition.

  128. named_namespace_definition::= original_namespace_definition | extension_namespace_definition.

  129. original_namespace_definition::= "namespace" identifier left_brace namespace_body right_brace .

  130. extension_namespace_definition::= "namespace" original_namespace_name left_brace namespace_body right_brace

  131. unnamed_namespace_definition::= "namespace" left_brace namespace_body right_brace

  132. namespace_body::= Opt( declaration_seq )

  133. namespace_alias_definition::= "namespace" identifier = qualified_namespace_specifier ";"

  134. qualified_namespace_specifier::= Opt(double_colon) Opt( nested_name_specifier ) namespace_name

  135. using_declaration::= "using" Opt( typename ) Opt(double_colon) nested_name_specifier unqualified_id ";" | "using" double_colon unqualified_id ";"

    ASM

  136. asm_definition::= "asm" "(" string_literal ")" ";"

    Linkage Specifications

  137. linkage_specification::= "extern" string_literal left_brace Opt( declaration_seq ) right_brace | "extern" string_literal declaration

    Declarations

  138. init_declarator_list::= init_declarator | init_declarator_list comma init_declarator
  139. init_declarator::= declarator Opt( initializer )

  140. declarator::= direct_declarator | ptr_operator declarator

  141. direct_declarator::= declarator_id | direct_declarator "(" parameter_declaration_clause ")" Opt( cv_qualifier_seq ) Opt( exception_specification ) | direct_declarator "[" Opt( constant_expression ) "]" | "(" declarator ")"

  142. ptr_operator::= "*" Opt( cv_qualifier_seq ) | "&" | Opt(double_colon) nested_name_specifier "*" Opt( cv_qualifier_seq )

  143. cv_qualifier_seq::= cv_qualifier Opt( cv_qualifier_seq )

  144. cv_qualifier::= "const" | "volatile"

  145. declarator_id::= Opt(double_colon) id_expression | Opt(double_colon) Opt( nested_name_specifier ) type_name

  146. type_id::= type_specifier_seq Opt( abstract_declarator )

  147. type_specifier_seq::= type_specifier Opt( type_specifier_seq )

  148. abstract_declarator::= ptr_operator Opt( abstract_declarator ) | direct_abstract_declarator

  149. direct_abstract_declarator::= Opt( direct_abstract_declarator ) "(" parameter_declaration_clause ")" Opt( cv_qualifier_seq ) Opt( exception_specification ) | Opt( direct_abstract_declarator ) "[" Opt( constant_expression ) "]" | "(" abstract_declarator ")"

  150. parameter_declaration_clause::= Opt( parameter_declaration_list ) Opt( "..." ) | parameter_declaration_list comma "..."

  151. parameter_declaration_list::= parameter_declaration | parameter_declaration_list comma parameter_declaration

  152. parameter_declaration::= decl_specifier_seq declarator | decl_specifier_seq declarator "=" assignment_expression | decl_specifier_seq Opt( abstract_declarator ) | decl_specifier_seq Opt( abstract_declarator ) "=" assignment_expression

  153. function_definition::= Opt( decl_specifier_seq ) declarator Opt( ctor_initializer ) function_body | Opt( decl_specifier_seq ) declarator function_try_block

  154. function_body::= compound_statement

  155. initializer::= "=" initializer_clause | "(" expression_list ")"
  156. initializer_clause::= assignment_expression | left_brace initializer_list Opt(comma ) right_brace | left_brace right_brace

  157. initializer_list::= L( initializer_clause).

    Classes

  158. class_name::= identifier | template_id

  159. class_specifier::= class_head left_brace Opt( member_specification ) right_brace

  160. class_head::= class_key Opt( identifier ) Opt( base_clause ) | class_key nested_name_specifier identifier Opt( base_clause )

  161. class_key::= "class" | "struct" | "union"

    Members

  162. member_specification::= member_declaration Opt( member_specification ) | access_specifier ":" Opt( member_specification )

  163. member_declaration::= Opt( decl_specifier_seq ) Opt( member_declarator_list ) ";" | function_definition Opt( ";" ) | qualified_id ";" | using_declaration | template_declaration

  164. member_declarator_list::= member_declarator | member_declarator_list comma member_declarator

  165. member_declarator::= declarator Opt( pure_specifier ) | declarator Opt( constant_initializer ) | Opt( identifier ) ":" constant_expression

  166. pure_specifier::= "=" "0"

  167. constant_initializer::= "=" constant_expression

  168. base_clause::= ":" base_specifier_list

  169. base_specifier_list::= base_specifier | base_specifier_list comma base_specifier

  170. base_specifier::= Opt(double_colon) Opt( nested_name_specifier ) class_name | "virtual" Opt( access_specifier ) Opt(double_colon) Opt( nested_name_specifier ) class_name | access_specifier Opt( virtual ) Opt(double_colon) Opt( nested_name_specifier ) class_name

  171. access_specifier::= "private" | "protected" |" public".

  172. conversion_function_id::= operator conversion_type_id

  173. conversion_type_id::= type_specifier_seq Opt( conversion_declarator )

  174. conversion_declarator::= ptr_operator Opt( conversion_declarator )

  175. ctor_initializer::= ":" mem_initializer_list

  176. mem::glossay=member.
  177. ctor::glossary=constructor.

  178. mem_initializer_list::= mem_initializer | mem_initializer comma mem_initializer_list.

  179. mem_initializer::= mem_initializer_id "(" Opt( expression_list ) ")."

  180. mem_initializer_id::= Opt(double_colon) Opt( nested_name_specifier ) class_name | identifier.

  181. postfix_expression::= postfix_expression "." id_expression | postfix_expression "->" id_expression | primary_expression.

  182. operator_function_id::= "operator" operator comma.

  183. operator::="new"Opt("[]")|"delete"Opt("[]")|"+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~" | "!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!=" | "<=" | ">=" | "&&" | "||" | "++" | "--" | comma | "->*" | "->" | "()" | "[]".

  184. template_declaration::= Opt( "export" ) "template" "<" template_parameter_list ">" declaration.

  185. template_parameter_list::=L( template_parameter).

  186. template_parameter::= type_parameter | parameter_declaration

  187. type_parameter::= "class" Opt( identifier ) | "class" Opt( identifier ) "=" type_id | typename Opt( identifier ) | typename Opt( identifier ) "=" type_id | "template" "<" template_parameter_list ">" "class" Opt( identifier ) | "template" "<" template_parameter_list ">" "class" Opt( identifier ) "=" template_name.

  188. template_id::= template_name "<" template_argument_list ">"

  189. template_name::= identifier. .
  190. template_argument_list::= L(template_argument).
  191. template_argument::= assignment_expression | type_id | template_name.

  192. elaborated_type_specifier::= typename Opt(double_colon) nested_name_specifier identifier | typename Opt(double_colon) nested_name_specifier identifier "<" template_argument_list ">" | . . . | simple_type_specifier ( Opt( expression_list ) ) | Opt(double_colon) "new" Opt( new_placement ) new_type_id Opt( new_initializer ) | Opt(double_colon) "new" Opt( new_placement ) "(" type_id ")" Opt( new_initializer ) | cast "<" type_id ">" "(" expression ")" | "(" type_id ")" cast_expression.

  193. explicit_instantiation::= template_declaration. Error in this definition was pointed out by David Wigg <wiggjd> South Bank University UK Fri, 25 Apr 2003 17:03:27 +0100. Thank you!

  194. explicit_specialization::= "template" "<" ">" declaration.

    Exceptions

  195. try_block::="try" compound_statement handler_seq.

  196. function_try_block::= "try" Opt( ctor_initializer ) function_body handler_seq.
  197. handler_seq::=Seq(handler).

  198. handler::= "catch" "(" exception_declaration ")" compound_statement

  199. exception_declaration::= type_specifier_seq declarator | type_specifier_seq abstract_declarator | type_specifier_seq | "...".

  200. throw_expression::= "throw"Opt( assignment_expression )

  201. exception_specification::= "throw"( Opt( type_id_list ) )

  202. type_id_list::= L( type_id ).

    Preprocessing

  203. preprocessing_file::= Opt( group )

  204. group::= Seq(group_part).

  205. group_part::= Opt( pp_tokens ) new_line | if_section | control_line.

  206. if_section::= if_group Opt( elif_groups ) Opt( else_group ) endif_line.

  207. if_group::= hash "if" constant_expression new_line Opt( group ) | hash "ifdef" identifier new_line Opt( group ) | hash "ifndef" identifier new_line Opt( group ).

  208. elif_groups::=Seq( elif_group).

  209. elif_group::= hash "elif" constant_expression new_line Opt( group )

  210. else_group::= hash "else" new_line Opt( group )

  211. endif_line::= hash "endif" new_line

  212. control_line::= hash control_line_body new_line.

  213. control_line_body::="include" pp_tokens | "define" identifier replacement_list | "define" identifier lparen Opt( identifier_list ) ) replacement_list | "undef" identifier | "line" pp_tokens | "error" Opt( pp_tokens ) | "pragma" Opt( pp_tokens ) | empty.

  214. lparen::=the left_paren character without preceding white_space.

  215. replacement_list::= Opt( pp_tokens ).

  216. pp_tokens::=Seq( preprocessing_token).

    . . . . . . . . . ( end of section Syntax of C++ as per Draft ANSI/ISO Standard December 1997) <<Contents | Index>>


Formulae and Definitions in Alphabetical Order