[Skip Navigation] [CSUSB] / [CNS] / [Comp Sci Dept] / [R J Botting] / [Samples] / c++.standard.syntax
[Index] [Contents] [Source Text] [About] [Notation] [Copyright] [Comment/Contact] [Search ]
Tue Sep 18 15:25:33 PDT 2007

Contents


    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

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

      Lexicon

    16. typeid::lexeme= "typeid".

      More to be worked out...

      Lexemes

    17. hex_quad::= hexadecimal_digit^4.

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

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

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

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

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

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

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

    25. pp_number::= (digit | "." digit ) #( digit | nondigit | ("e" | "E" ) sign | ".").

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

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

    28. digit::= "0".."9".

    29. 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".

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

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

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

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

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

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

    36. octal_digit::= "0".."7".

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

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

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

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

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

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

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

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

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

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

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

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

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

    50. sign::= plus | minus.

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

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

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

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

      Basic Ideas

    55. translation_unit::= Opt( declaration_seq ).

      Names

    56. id_expression::= unqualified_id | qualified_id.

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

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

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

    60. class_or_namespace_name::= class_name | namespace_name.

      Expressions

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

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

    63. 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 | "++" | "--").

    64. expression_list::= assignment_expression | expression_list comma assignment_expression.

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

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

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

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

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

    70. new_placement::= left_paren expression_list right_paren.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    92. expression::= assignment_expression | expression comma assignment_expression.

    93. constant_expression::=conditional_expression.

      Statements

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

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

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

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

    98. statement_seq::= Seq( statement).

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

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

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

    102. for_init_statement::= expression_statement | simple_declaration.

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

    104. declaration_statement::= block_declaration.

    105. declaration_seq::= Seq( declaration ).

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

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

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

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

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

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

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

    113. typedef_name::= identifier.

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

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

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

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

    118. enum_name::= identifier.

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

    120. enumerator_list::= enumerator_definition | enumerator_list comma enumerator_definition.

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

    122. enumerator::= identifier.

      Namespaces

    123. namespace_name::= original_namespace_name | namespace_alias.

    124. original_namespace_name::= identifier.

    125. namespace_definition::= named_namespace_definition | unnamed_namespace_definition.

    126. named_namespace_definition::= original_namespace_definition | extension_namespace_definition.

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

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

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

    130. namespace_body::= Opt( declaration_seq )

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

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

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

      ASM

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

      Linkage Specifications

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

      Declarations

    136. init_declarator_list::= init_declarator | init_declarator_list comma init_declarator
    137. init_declarator::= declarator Opt( initializer )

    138. declarator::= direct_declarator | ptr_operator declarator

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

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

    141. cv_qualifier_seq::= cv_qualifier Opt( cv_qualifier_seq )

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

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

    144. type_id::= type_specifier_seq Opt( abstract_declarator )

    145. type_specifier_seq::= type_specifier Opt( type_specifier_seq )

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

    147. 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 ")"

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

    149. parameter_declaration_list::= parameter_declaration | parameter_declaration_list comma parameter_declaration

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

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

    152. function_body::= compound_statement

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

    155. initializer_list::= L( initializer_clause).

      Classes

    156. class_name::= identifier | template_id

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

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

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

      Members

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

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

    162. member_declarator_list::= member_declarator | member_declarator_list comma member_declarator

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

    164. pure_specifier::= "=" "0"

    165. constant_initializer::= "=" constant_expression

    166. base_clause::= ":" base_specifier_list

    167. base_specifier_list::= base_specifier | base_specifier_list comma base_specifier

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

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

    170. conversion_function_id::= operator conversion_type_id

    171. conversion_type_id::= type_specifier_seq Opt( conversion_declarator )

    172. conversion_declarator::= ptr_operator Opt( conversion_declarator )

    173. ctor_initializer::= ":" mem_initializer_list

    174. mem::glossay=member.
    175. ctor::glossary=constructor.

    176. mem_initializer_list::= mem_initializer | mem_initializer comma mem_initializer_list.

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

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

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

    180. operator_function_id::= "operator" operator comma.

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

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

    183. template_parameter_list::=L( template_parameter).

    184. template_parameter::= type_parameter | parameter_declaration

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

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

    187. template_name::= identifier. .
    188. template_argument_list::= L(template_argument).
    189. template_argument::= assignment_expression | type_id | template_name.

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

    191. explicit_instantiation::= "template" declaration.

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

      Exceptions

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

    194. function_try_block::= "try" Opt( ctor_initializer ) function_body handler_seq.
    195. handler_seq::=Seq(handler).

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

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

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

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

    200. type_id_list::= L( type_id ).

      Preprocessing

    201. preprocessing_file::= Opt( group )

    202. group::= Seq(group_part).

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

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

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

    206. elif_groups::=Seq( elif_group).

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

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

    209. endif_line::= hash "endif" new_line

    210. control_line::= hash control_line_body new_line.

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

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

    213. replacement_list::= Opt( pp_tokens ).

    214. pp_tokens::=Seq( preprocessing_token).

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

End