. 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: .See http://www/dick/c++std See .See http://www/dick/c++std/index.html#Syntax 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 .See mailto:rbotting@wiley.csusb.edu to help me correct any errors. . Metalanguage .Box 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`. .See http://www/dick//maths/math.syntax.html .Close.Box 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. .Open Syntax of C++ as per Draft ANSI/ISO Standard December 1997 . Characters characters::=$ASCII.char ~ "$", ASCII::=see following .See http://www/dick/samples/comp.text.ASCII.html backslash::=$ASCII.backslash. .See http://www/dick/samples/comp.text.ASCII.html#backslash hash::=$ASCII.sharp .See http://www/dick/samples/comp.text.ASCII.html#sharp comma::=$ASCII.comma, .See http://www/dick/samples/comp.text.ASCII.html#comma quotes::=$ASCII.double_quote, .See http://www/dick/samples/comp.text.ASCII.html#quotation quote::=$ASCII.single_quote, .See http://www/dick/samples/comp.text.ASCII.html#apostrophe new_line::=`the new_line character`. .See http://www/dick/samples/comp.text.ASCII.html#EOLN double_colon::=$ASCII.colon $ASCII.colon, .See http://www/dick/samples/comp.text.ASCII.html#colon 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). .Close Syntax of C++ as per Draft ANSI/ISO Standard December 1997