/*
C++ syntax abstracted from:
ISO/IEC 14882 Second Edition 2003-10-15
Annex A (informative) - Grammar summary
*/
%encoding binary
%entrypoint translation-unit preprocessing-file
// A.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:
'[^\n>]' // any member of the source character set except the new-line character and >
q-char-sequence:
q-char
| q-char-sequence q-char
q-char:
'[^\n"]' // any member of the source character set except the new-line character 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:
universal-character-name
| '[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'
digit:
'[0123456789]'
preprocessing-op-or-punc:
"{" | "}" | "[" | "]" | "#" | "##" | "(" | ")"
| "<:" | ":>" | "<%" | "%>" | "%:" | "%:%:" | ";" | ":" | "..."
| "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-suffix?
| octal-literal integer-suffix?
| hexadecimal-literal integer-suffix?
decimal-literal:
nonzero-digit
| decimal-literal digit
octal-literal:
"0"
| octal-literal octal-digit
hexadecimal-literal:
'0[xX]' hexadecimal-digit
| hexadecimal-literal hexadecimal-digit
nonzero-digit:
'[123456789]'
octal-digit:
'[01234567]'
hexadecimal-digit:
'[0123456789abcdefABCDEF]'
integer-suffix:
unsigned-suffix long-suffix?
| long-suffix unsigned-suffix?
unsigned-suffix:
'[uU]'
long-suffix:
'[lL]'
character-literal:
"'" c-char-sequence "'"
| "L'" c-char-sequence "'"
c-char-sequence:
c-char
| c-char-sequence c-char
c-char:
'[^\'\\\n]' // 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:
"\\'" | '\\"' | "\\?" | "\\\\"
| "\\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-part? floating-suffix?
| digit-sequence exponent-part floating-suffix?
fractional-constant:
digit-sequence? "." digit-sequence
| digit-sequence "."
exponent-part:
'[eE]' sign? digit-sequence
sign:
'[+\-]'
digit-sequence:
digit
| digit-sequence digit
floating-suffix:
'[flFL]'
string-literal:
'"' s-char-sequence? '"'
| 'L"' s-char-sequence? '"'
s-char-sequence:
s-char
| s-char-sequence s-char
s-char:
'[^"\\\n]' // 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"
// A.3 Basic concepts [gram.basic]
translation-unit:
declaration-seq?
// A.4 Expressions [gram.expr]
primary-expression:
literal
| "this"
| "(" expression ")"
| id-expression
id-expression:
unqualified-id
| qualified-id
unqualified-id:
identifier
| operator-function-id
| conversion-function-id
| "~" class-name
| template-id
qualified-id:
"::"? nested-name-specifier "template"? unqualified-id
| "::" identifier
| "::" operator-function-id
| "::" template-id
nested-name-specifier:
class-or-namespace-name "::" nested-name-specifier?
| class-or-namespace-name "::" "template" nested-name-specifier
class-or-namespace-name:
class-name
| namespace-name
postfix-expression:
primary-expression
| postfix-expression "[" expression "]"
| postfix-expression "(" expression-list? ")"
| simple-type-specifier "(" expression-list? ")"
| "typename" "::"? nested-name-specifier identifier "(" expression-list? ")"
| "typename" "::"? nested-name-specifier "template"? template-id "(" expression-list? ")"
| postfix-expression "." "template"? id-expression
| postfix-expression "->" "template"? 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:
"::"? nested-name-specifier? type-name "::" "~" type-name
| "::"? nested-name-specifier "template" template-id "::" "~" type-name
| "::"? 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:
"::"? "new" new-placement? new-type-id new-initializer?
| "::"? "new" new-placement? "(" type-id ")" new-initializer?
new-placement:
"(" expression-list ")"
new-type-id:
type-specifier-seq new-declarator?
new-declarator:
ptr-operator new-declarator?
| direct-new-declarator
direct-new-declarator:
"[" expression "]"
| direct-new-declarator "[" constant-expression "]"
new-initializer:
"(" expression-list? ")"
delete-expression:
"::"? "delete" cast-expression
| "::"? "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:
"=" | "*=" | "/=" | "%=" | "+=" | "-=" | ">>=" | "<<=" | "&=" | "^=" | "|="
expression:
assignment-expression
| expression "," assignment-expression
constant-expression:
conditional-expression
// A.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:
expression? ";"
compound-statement:
"{" statement-seq? "}"
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 condition? ";" expression? ")" statement
for-init-statement:
expression-statement
| simple-declaration
jump-statement:
"break" ";"
"continue" ";"
"return" expression? ";"
"goto" identifier ";"
declaration-statement:
block-declaration
// A.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-seq? init-declarator-list? ";"
decl-specifier:
storage-class-specifier
| type-specifier
| function-specifier
| "friend"
| "typedef"
decl-specifier-seq:
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:
"::"? nested-name-specifier? type-name
| "::"? nested-name-specifier "template" template-id
| "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 "::"? nested-name-specifier? identifier
| class-key "::"? nested-name-specifier? "template"? template-id
| "enum" "::"? nested-name-specifier? identifier
| "typename" "::"? nested-name-specifier identifier
| "typename" "::"? nested-name-specifier "template"? template-id
enum-name:
identifier
enum-specifier:
"enum" identifier? "{" enumerator-list? "}"
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-seq?
namespace-alias:
identifier
namespace-alias-definition:
"namespace" identifier "=" qualified-namespace-specifier ";"
qualified-namespace-specifier:
"::"? nested-name-specifier? namespace-name
using-declaration:
"using" "typename"? "::"? nested-name-specifier unqualified-id ";"
| "using" "::" unqualified-id ";"
using-directive:
"using" "namespace" "::"? nested-name-specifier? namespace-name ";"
asm-definition:
"asm" "(" string-literal ")" ";"
linkage-specification:
"extern" string-literal "{" declaration-seq? "}"
| "extern" string-literal declaration
// A.7 Declarators [gram.dcl.decl]
init-declarator-list:
init-declarator
| init-declarator-list "," init-declarator
init-declarator:
declarator initializer?
declarator:
direct-declarator
| ptr-operator declarator
direct-declarator:
declarator-id
| direct-declarator "(" parameter-declaration-clause ")" cv-qualifier-seq? exception-specification?
| direct-declarator "[" constant-expression? "]"
| "(" declarator ")"
ptr-operator:
"*" cv-qualifier-seq?
| "&"
| "::"? nested-name-specifier "*" cv-qualifier-seq?
cv-qualifier-seq:
cv-qualifier cv-qualifier-seq?
cv-qualifier:
"const"
| "volatile"
declarator-id:
id-expression
| "::"? nested-name-specifier? type-name
type-id:
type-specifier-seq abstract-declarator?
type-specifier-seq:
type-specifier type-specifier-seq?
abstract-declarator:
ptr-operator abstract-declarator?
| direct-abstract-declarator
direct-abstract-declarator:
direct-abstract-declarator?
| "(" parameter-declaration-clause ")" cv-qualifier-seq? exception-specification?
| direct-abstract-declarator? "[" constant-expression? "]"
| "(" abstract-declarator ")"
parameter-declaration-clause:
parameter-declaration-list? "..."?
| 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-declarator?
| decl-specifier-seq abstract-declarator? "=" assignment-expression
function-definition:
decl-specifier-seq? declarator ctor-initializer? function-body
| decl-specifier-seq? declarator function-try-block
function-body:
compound-statement
initializer:
"=" initializer-clause
| "(" expression-list ")"
initializer-clause:
assignment-expression
| "{" initializer-list ","? "}"
| "{" "}"
initializer-list:
initializer-clause
| initializer-list "," initializer-clause
// A.8 Classes [gram.class]
class-name:
identifier
| template-id
class-specifier:
class-head "{" member-specification? "}"
class-head:
class-key identifier? base-clause?
| class-key nested-name-specifier identifier base-clause?
| class-key nested-name-specifier? template-id base-clause?
class-key:
"class"
| "struct"
| "union"
member-specification:
member-declaration member-specification?
| access-specifier ":" member-specification?
member-declaration:
decl-specifier-seq? member-declarator-list? ";"
| function-definition ";"?
| "::"? nested-name-specifier "template"? unqualified-id ";"
| using-declaration
| template-declaration
member-declarator-list:
member-declarator
| member-declarator-list "," member-declarator
member-declarator:
declarator pure-specifier?
| declarator constant-initializer?
| identifier? ":" constant-expression
pure-specifier:
"=" "0"
constant-initializer:
"=" constant-expression
// A.9 Derived classes [gram.class.derived]
base-clause:
":" base-specifier-list
base-specifier-list:
base-specifier
| base-specifier-list "," base-specifier
base-specifier:
"::"? nested-name-specifier? class-name
| "virtual" access-specifier? "::"? nested-name-specifier? class-name
| access-specifier "virtual"? "::"? nested-name-specifier? class-name
access-specifier:
"private"
| "protected"
| "public"
// A.10 Special member functions [gram.special]
conversion-function-id:
"operator" conversion-type-id
conversion-type-id:
type-specifier-seq conversion-declarator?
conversion-declarator:
ptr-operator conversion-declarator?
ctor-initializer:
":" mem-initializer-list
mem-initializer-list:
mem-initializer
| mem-initializer "," mem-initializer-list
mem-initializer:
mem-initializer-id "(" expression-list? ")"
mem-initializer-id:
"::"? nested-name-specifier? class-name
| identifier
// A.11 Overloading [gram.over]
operator-function-id:
"operator" operator
| "operator" operator "<" template-argument-list? ">"
operator:
"new" | "delete" | "new[]" | "delete[]"
| "+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "~"
| "!" | "=" | "<" | ">" | "+=" | "-=" | "*=" | "/=" | "%="
| "^=" | "&=" | "|=" | "<<" | ">>" | ">>=" | "<<=" | "==" | "!="
| "<=" | ">=" | "&&" | "||" | "++" | "--" | "," | "->*" | "->"
| "()" | "[]"
// A.12 Templates [gram.temp]
template-declaration:
"export"? "template" "<" template-parameter-list ">" declaration
template-parameter-list:
template-parameter
| template-parameter-list "," template-parameter
template-parameter:
type-parameter
| parameter-declaration
type-parameter:
"class" identifier?
| "class" identifier? "=" type-id
| "typename" identifier?
| "typename" identifier? "=" type-id
| "template" "<" template-parameter-list ">" "class" identifier?
| "template" "<" template-parameter-list ">" "class" identifier? "=" id-expression
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
| id-expression
explicit-instantiation:
"template" declaration
explicit-specialization:
"template" "<" ">" declaration
// A.13 Exception handling [gram.except]
try-block:
"try" compound-statement handler-seq
function-try-block:
"try" ctor-initializer? function-body handler-seq
handler-seq:
handler handler-seq?
handler:
"catch" "(" exception-declaration ")" compound-statement
exception-declaration:
type-specifier-seq declarator
| type-specifier-seq abstract-declarator
| type-specifier-seq
| "..."
throw-expression:
"throw" assignment-expression?
exception-specification:
"throw" "(" type-id-list? ")"
type-id-list:
type-id
| type-id-list "," type-id
// A.14 Preprocessing directives [gram.cpp]
preprocessing-file:
group?
group:
group-part
| group group-part
group-part:
pp-tokens? new-line
| if-section
| control-line
if-section:
if-group elif-groups? else-group? endif-line
if-group:
"#" "if" constant-expression new-line group?
| "#" "ifdef" identifier new-line group?
| "#" "ifndef" identifier new-line group?
elif-groups:
elif-group
| elif-groups elif-group
elif-group:
"#" "elif" constant-expression new-line group?
else-group:
"#" "else" new-line group?
endif-line:
"#" "endif" new-line
control-line:
"#" "include" pp-tokens new-line
| "#" "define" identifier replacement-list new-line
| "#" "define" identifier-lparen identifier-list? ")" replacement-list new-line
| "#" "undef" identifier new-line
| "#" "line" pp-tokens new-line
| "#" "error" pp-tokens? new-line
| "#" "pragma" pp-tokens? new-line
| "#" new-line
%explicit_whitespace
identifier-lparen:
identifier "(" // a ( character not immediately preceded by white-space
%implicit_whitespace
replacement-list:
pp-tokens?
identifier-list:
identifier ( "," identifier )*
pp-tokens:
preprocessing-token
| pp-tokens preprocessing-token
new-line:
'\n' | '/\z' /* the new-line character */ /* or the end of the file, unconsumed */
|