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:
- defined_term::=definition_of_that_term.
Plus
- #(X)::=A sequence of zero or more X'x.
- O(X)::=An optional X.
- N(X)::=One or more X's.
- L(X)::=A comma separated list of X's.
- X^n::=a sequence of n X's.
- A~B::=Any A that is not a B.
[ math.syntax.html ]
The following are used in the C++ syntax only:
- Opt(X)::=O(X), an optional X.
- Seq(X)::=N(X), a sequence of one or more X's.
Syntax of C++ as per Draft ANSI/ISO Standard December 1997
Characters
- characters::=ASCII.char ~ "$",
- ASCII::=see following
[ comp.text.ASCII.html ]
- backslash::=ASCII.backslash.
[ backslash in comp.text.ASCII ]
- hash::=ASCII.sharp
[ sharp in comp.text.ASCII ]
- comma::=ASCII.comma,
[ comma in comp.text.ASCII ]
- quotes::=ASCII.double_quote,
[ quotation in comp.text.ASCII ]
- quote::=ASCII.single_quote,
[ apostrophe in comp.text.ASCII ]
- new_line::=the new_line character.
[ EOLN in comp.text.ASCII ]
- double_colon::=ASCII.colon ASCII.colon,
[ colon in comp.text.ASCII ]
- left_paren::="(".
- right_paren::=")".
- left_brace::lexeme=
"{".
- right_brace::lexeme=
"}".
- left_bracket::lexeme=
"[".
- right_bracket::lexeme=
"]".
Lexicon
- typeid::lexeme=
"typeid".
More to be worked out...
Lexemes
- hex_quad::= hexadecimal_digit^4.
- universal_character_name::= backslash "u" hex_quad | backslash "U" hex_quad^2.
- 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.
- keyword::= predefined_keyword | introduced_keyword.
New context-dependent keywords are introduced by type_def, namespace, class,
enumeration, and template definitions.
- header_name::= "<" h_char_sequence">" | quotes q_char_sequence quotes.
- h_char_sequence::=Seq(characters~(">" | new_line)).
- q_char_sequence::=Seq(characters~(quotes | new_line)).
- pp_number::= (digit | "." digit ) #( digit | nondigit | ("e" | "E" ) sign | ".").
- identifier::= nondigit #( nondigit | digit).
- nondigit::= universal_character_name | ASCII.letter | ASCII.underscore.
- digit::= "0".."9".
- 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".
- literal::= integer_literal | character_literal | floating_literal | string_literal | boolean_literal.
- integer_literal::= decimal_literal Opt( integer_suffix ) | octal_literal Opt( integer_suffix ) | hexadecimal_literal Opt( integer_suffix ).
- decimal_literal::= nonzero_digit #(digit).
- octal_literal::= "0" #(octal_digit).
- hexadecimal_literal::=( "0x" | "0X") #(hexadecimal_digit).
- nonzero_digit::= digit~"0".
- octal_digit::= "0".."7".
- hexadecimal_digit::= "0".."9" | "a".."f" | "A".."F".
- integer_suffix::= unsigned_suffix Opt( long_suffix ) | long_suffix Opt( unsigned_suffix ).
- unsigned_suffix::= "u" | "U".
- long_suffix::= "l" | "L".
- character_literal::= quote Seq(c_char) quote | "L" quote Seq(c_char) quote .
- c_char::=characters~( quote | backslash | new_line ) | escape_sequence | universal_character_name.
- escape_sequence::= simple_escape_sequence |octal_escape_sequence | hexadecimal_escape_sequence.
- simple_escape_sequence::= backslash ( quote | quotes | "?" | backslash | "a" | "b" | "f" |"n" | "r" | "t" | "v" ).
- octal_escape_sequence::= backslash (octal_digit | octal_digit^2 | octal_digit^3).
- hexadecimal_escape_sequence::= backslash "x" Seq(hexadecimal_digit).
- floating_literal::= fractional_constant Opt( exponent_part ) Opt( floating_suffix ) | Seq(digit) exponent_part Opt( floating_suffix ).
- fractional_constant::= Opt( Seq(digit) ) "." Seq(digit) | Seq(digit) ".".
- exponent_part::= "e" Opt( sign ) Seq(digit) | "E" Opt( sign ) Seq(digit).
- sign::= plus | minus.
- floating_suffix::= "f" | "l" | "F" | "L".
- string_literal::= Opt("L") quotes Opt( Seq(s_char) ) quotes.
- s_char::=(characters ~ ( quotes | backslash | new_line ))| escape_sequence | universal_character_name.
- boolean_literal::= "false" | "true".
Basic Ideas
- translation_unit::= Opt( declaration_seq ).
Names
- id_expression::= unqualified_id | qualified_id.
- unqualified_id::= identifier | operator_function_id | conversion_function_id | "~" class_name | template_id.
- qualified_id::= nested_name_specifier Opt( "template" ) unqualified_id.
- nested_name_specifier::= class_or_namespace_name double_colon Opt( nested_name_specifier ).
- class_or_namespace_name::= class_name | namespace_name.
Expressions
- primary_expression::= literal | "this" | double_colon identifier | double_colon operator_function_id | double_colon qualified_id | "(" expression ")" | id_expression.
- postfix_expression::=( primary_expression | simple_type_specifier "(" Opt( expression_list ) ")" | cast "<" type_id ">" "(" expression ")" | "typeid" "(" (expression | type_id ")") ) postfix_operations.
- 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 | "++" | "--").
- expression_list::= assignment_expression | expression_list comma assignment_expression.
- cast::="dynamic_cast" | "static_cast" | "const_cast" | "reinterpret_cast".
- 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.
- unary_expression::= postfix_expression | "++" cast_expression | "--" cast_expression | unary_operator cast_expression | "sizeof" unary_expression | "sizeof" "(" type_id ")" | new_expression | delete_expression.
- unary_operator::= "|" | "*" | "&" | "+" | "-" | "!" | "~".
- new_expression::= Opt(double_colon) "new" Opt( new_placement ) ( new_type_id | "(" type_id ")" ) Opt( new_initializer ).
- new_placement::= left_paren expression_list right_paren.
- new_type_id::= type_specifier_seq Opt( new_declarator ).
- new_declarator::= ptr_operator Opt( new_declarator ) | direct_new_declarator.
- direct_new_declarator::= Seq(left_bracket expression right_bracket).
- new_initializer::= left_paren Opt( expression_list ) right_paren.
- delete_expression::= Opt(double_colon) "delete" Opt( "[]" ) cast_expression.
- cast_expression::= unary_expression | left_paren type_id right_paren cast_expression.
- pm_expression::= #( cast_expression ( ".*" | "->*" )) cast_expression.
- For Expr, Op, infix(Expr, Op)::= Expr #(Op Expr).
- multiplicative_expression::=infix(pm_expression, ("*" | "/" | "%" )).
- additive_expression::=infix( multiplicative_expression, ("+" | "-")).
- shift_expression::=infix( additive_expression, ("<<" | ">>" )).
- relational_expression::= infix( shift_expression, ("<" | ">" |"<=" | ">=" )).
- equality_expression::= infix( relational_expression, ("==" | "!=")).
- and_expression::= infix( equality_expression, "&" ).
- exclusive_or_expression::= infix( and_expression, "^").
- inclusive_or_expression::= infix( exclusive_or_expression , "|").
- logical_and_expression::= infix( inclusive_or_expression, "&&" ).
- logical_or_expression::= infix( 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::= "|" | "=" | "*=" | "/= %=" | " +=" | "-=" | ">>=" | "<<=" | "&=" | "^=" | "|=".
- expression::= assignment_expression | expression comma assignment_expression.
- constant_expression::=conditional_expression.
Statements
- 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::= Opt( expression ) ";" .
- compound_statement::= left_brace Opt( statement_seq ) right_brace.
- statement_seq::= 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 Opt( condition ) ";" Opt( expression ) ")" statement.
- for_init_statement::= expression_statement | simple_declaration.
- jump_statement::= "break" ";" | "continue" ";" | "return" Opt( expression ) ";" | "goto" identifier ";" .
- declaration_statement::= block_declaration.
- declaration_seq::= 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::= Opt( decl_specifier_seq ) Opt( init_declarator_list ) ";" .
- decl_specifier::= storage_class_specifier | type_specifier | function_specifier | "friend" | "typedef".
- decl_specifier_seq::= Opt( decl_specifier_seq ) 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(double_colon ) Opt( nested_name_specifier ) 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(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
- enum_name::= identifier.
- enum_specifier::= "enum" Opt( identifier ) left_brace Opt( enumerator_list ) right_brace.
- enumerator_list::= enumerator_definition | enumerator_list comma enumerator_definition.
- enumerator_definition::= enumerator | enumerator "=" constant_expression.
- enumerator::= identifier.
Namespaces
- 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 left_brace namespace_body right_brace .
- extension_namespace_definition::= "namespace" original_namespace_name left_brace namespace_body right_brace
- unnamed_namespace_definition::= "namespace" left_brace namespace_body right_brace
- namespace_body::= Opt( declaration_seq )
- namespace_alias_definition::= "namespace" identifier = qualified_namespace_specifier ";"
- qualified_namespace_specifier::= Opt(double_colon) Opt( nested_name_specifier ) namespace_name
- using_declaration::= "using" Opt( typename ) Opt(double_colon) nested_name_specifier unqualified_id ";" | "using" double_colon unqualified_id ";"
ASM
- asm_definition::= "asm" "(" string_literal ")" ";"
Linkage Specifications
- linkage_specification::= "extern" string_literal left_brace Opt( declaration_seq ) right_brace | "extern" string_literal declaration
Declarations
- init_declarator_list::= init_declarator | init_declarator_list comma init_declarator
- init_declarator::= declarator Opt( initializer )
- declarator::= direct_declarator | ptr_operator declarator
- direct_declarator::= declarator_id | direct_declarator "(" parameter_declaration_clause ")" Opt( cv_qualifier_seq ) Opt( exception_specification ) | direct_declarator "[" Opt( constant_expression ) "]" | "(" declarator ")"
- ptr_operator::= "*" Opt( cv_qualifier_seq ) | "&" | Opt(double_colon) nested_name_specifier "*" Opt( cv_qualifier_seq )
- cv_qualifier_seq::= cv_qualifier Opt( cv_qualifier_seq )
- cv_qualifier::= "const" | "volatile"
- declarator_id::= Opt(double_colon) id_expression | Opt(double_colon) Opt( nested_name_specifier ) type_name
- type_id::= type_specifier_seq Opt( abstract_declarator )
- type_specifier_seq::= type_specifier Opt( type_specifier_seq )
- abstract_declarator::= ptr_operator Opt( abstract_declarator ) | direct_abstract_declarator
- 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 ")"
- parameter_declaration_clause::= Opt( parameter_declaration_list ) Opt( "..." ) | parameter_declaration_list comma "..."
- parameter_declaration_list::= parameter_declaration | parameter_declaration_list comma parameter_declaration
- 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
- function_definition::= Opt( decl_specifier_seq ) declarator Opt( ctor_initializer ) function_body | Opt( decl_specifier_seq ) declarator function_try_block
- function_body::= compound_statement
- initializer::= "=" initializer_clause | "(" expression_list ")"
- initializer_clause::= assignment_expression | left_brace initializer_list Opt(comma ) right_brace | left_brace right_brace
- initializer_list::= L( initializer_clause).
Classes
- class_name::= identifier | template_id
- class_specifier::= class_head left_brace Opt( member_specification ) right_brace
- class_head::= class_key Opt( identifier ) Opt( base_clause ) | class_key nested_name_specifier identifier Opt( base_clause )
- class_key::= "class" | "struct" | "union"
Members
- member_specification::= member_declaration Opt( member_specification ) | access_specifier ":" Opt( member_specification )
- member_declaration::= Opt( decl_specifier_seq ) Opt( member_declarator_list ) ";" | function_definition Opt( ";" ) | qualified_id ";" | using_declaration | template_declaration
- member_declarator_list::= member_declarator | member_declarator_list comma member_declarator
- member_declarator::= declarator Opt( pure_specifier ) | declarator Opt( constant_initializer ) | Opt( identifier ) ":" constant_expression
- pure_specifier::= "=" "0"
- constant_initializer::= "=" constant_expression
- base_clause::= ":" base_specifier_list
- base_specifier_list::= base_specifier | base_specifier_list comma base_specifier
- 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
- access_specifier::= "private" | "protected" |" public".
- conversion_function_id::= operator conversion_type_id
- conversion_type_id::= type_specifier_seq Opt( conversion_declarator )
- conversion_declarator::= ptr_operator Opt( conversion_declarator )
- ctor_initializer::= ":" mem_initializer_list
- mem::glossay=member.
- ctor::glossary=constructor.
- mem_initializer_list::= mem_initializer | mem_initializer comma mem_initializer_list.
- mem_initializer::= mem_initializer_id "(" Opt( expression_list ) ")."
- mem_initializer_id::= Opt(double_colon) Opt( nested_name_specifier ) class_name | identifier.
- postfix_expression::= postfix_expression "." id_expression | postfix_expression "->" id_expression | primary_expression.
- operator_function_id::= "operator" operator comma.
- operator::="new"Opt("[]")|"delete"Opt("[]")|"+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~" | "!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!=" | "<=" | ">=" | "&&" | "||" | "++" | "--" | comma | "->*" | "->" | "()" | "[]".
- template_declaration::= Opt( "export" ) "template" "<" template_parameter_list ">" declaration.
- template_parameter_list::=L( template_parameter).
- template_parameter::= type_parameter | parameter_declaration
- 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.
- template_id::= template_name "<" template_argument_list ">"
- template_name::= identifier.
.
- template_argument_list::= L(template_argument).
- template_argument::= assignment_expression | type_id | template_name.
- 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.
- explicit_instantiation::= "template" declaration.
- explicit_specialization::= "template" "<" ">" declaration.
Exceptions
- try_block::="try" compound_statement handler_seq.
- function_try_block::= "try" Opt( ctor_initializer ) function_body handler_seq.
- handler_seq::=Seq(handler).
- handler::= "catch" "(" exception_declaration ")" compound_statement
- exception_declaration::= type_specifier_seq declarator | type_specifier_seq abstract_declarator | type_specifier_seq | "...".
- throw_expression::= "throw"Opt( assignment_expression )
- exception_specification::= "throw"( Opt( type_id_list ) )
- type_id_list::= L( type_id ).
Preprocessing
- preprocessing_file::= Opt( group )
- group::= Seq(group_part).
- group_part::= Opt( pp_tokens ) new_line | if_section | control_line.
- if_section::= if_group Opt( elif_groups ) Opt( else_group ) endif_line.
- if_group::= hash "if" constant_expression new_line Opt( group ) | hash "ifdef" identifier new_line Opt( group ) | hash "ifndef" identifier new_line Opt( group ).
- elif_groups::=Seq( elif_group).
- elif_group::= hash "elif" constant_expression new_line Opt( group )
- else_group::= hash "else" new_line Opt( group )
- endif_line::= hash "endif" new_line
- control_line::= hash control_line_body new_line.
- 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.
- lparen::=the left_paren character without preceding white_space.
- replacement_list::= Opt( pp_tokens ).
- pp_tokens::=Seq( preprocessing_token).
. . . . . . . . . ( end of section Syntax of C++ as per Draft ANSI/ISO Standard December 1997) <<Contents | End>>