cplusplus
cplusplus copied to clipboard
Changing "specs/grammar.txt" to an EBNF understood by https://www.bottlecaps.de/rr/ui
If we change "specs/grammar.txt" to an EBNF understood by https://www.bottlecaps.de/rr/ui we can get a nice navigable railroad diagram representation of it that can help document/develop/debug this project grammar, follow the instructions shown bellow:
//
// EBNF to be viewd at https://www.bottlecaps.de/rr/ui
//
// Copy and paste this at https://www.bottlecaps.de/rr/ui in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//
//
//To facilitate start navigating
//
cplusplus ::=
preprocessing-file? translation-unit
//== lex.tex
n-char ::=
"{any member of the translation character set except the \unicode{007d}{right curly bracket} or new-line character}"
n-char-sequence ::=
n-char
| n-char-sequence n-char
named-universal-character ::=
"\N{" n-char-sequence "}"
hex-quad ::=
hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
simple-hexadecimal-digit-sequence ::=
hexadecimal-digit
| simple-hexadecimal-digit-sequence hexadecimal-digit
universal-character-name ::=
"\u" hex-quad
| "\U" hex-quad hex-quad
| "\u{" simple-hexadecimal-digit-sequence "}"
| named-universal-character
preprocessing-token ::=
header-name
| "import"
| "module"
| "export"
| identifier
| pp-number
| character-literal
| user-defined-character-literal
| string-literal
| user-defined-string-literal
| preprocessing-op-or-punc
| "{each non-whitespace character that cannot be one of the above}"
//token ::=
// identifier
// | keyword
// | literal
// | operator-or-punctuator
header-name ::=
"<" h-char-sequence ">"
| '"' q-char-sequence '"'
h-char-sequence ::=
h-char
| h-char-sequence h-char
h-char ::=
"{any member of the translation character set except new-line and \unicode{003e}{greater-than sign}}"
q-char-sequence ::=
q-char
| q-char-sequence q-char
q-char ::=
"{any member of the translation character set except new-line and \unicode{0022}{quotation mark}}"
pp-number ::=
digit
| "." digit
| pp-number identifier-continue
| pp-number "'" digit
| pp-number "'" nondigit
| pp-number "e" sign
| pp-number "E" sign
| pp-number "p" sign
| pp-number "P" sign
| pp-number "."
identifier ::=
identifier-start
| identifier identifier-continue
identifier-start ::=
nondigit
| "{an element of the translation character set with the Unicode property XID_Start}"
identifier-continue ::=
digit
| nondigit
| "{an element of the translation character set with the Unicode property XID_Continue}"
nondigit ::=
"a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m"
| "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
| "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M"
| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "_"
digit ::=
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
keyword ::=
"{any identifier listed in lex.key}"
| "import"
| "module"
| "export"
preprocessing-op-or-punc ::=
preprocessing-operator
| operator-or-punctuator
preprocessing-operator ::=
"#" | "##" | "%:" | "%:%:"
operator-or-punctuator ::=
"{" | "}" | "[" | "]" | "(" | ")"
| "<:" | ":>" | "<%" | "%>" | ";" | ":" | "..."
| "?" | "::" | "." | ".*" | "->" | "->*" | "~"
| "!" | "+" | "-" | "*" | "/" | "%" | "^" | "&" | "|"
| "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|="
| "==" | "!=" | "<" | ">" | "<=" | ">=" | "<=>" | "&&" | "||"
| "<<" | ">>" | "<<=" | ">>=" | "++" | "--" | ","
| "and" | "or" | "xor" | "not" | "bitand" | "bitor" | "compl"
| "and_eq" | "or_eq" | "xor_eq" | "not_eq"
literal ::=
integer-literal
| character-literal
| floating-point-literal
| string-literal
| boolean-literal
| pointer-literal
| user-defined-literal
integer-literal ::=
binary-literal integer-suffix?
| octal-literal integer-suffix?
| decimal-literal integer-suffix?
| hexadecimal-literal integer-suffix?
binary-literal ::=
"0b" binary-digit
| "0B" binary-digit
| binary-literal "'"? binary-digit
octal-literal ::=
"0"
| octal-literal "'"? octal-digit
decimal-literal ::=
nonzero-digit
| decimal-literal "'"? digit
hexadecimal-literal ::=
hexadecimal-prefix hexadecimal-digit-sequence
binary-digit ::=
"0" | "1"
octal-digit ::=
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7"
nonzero-digit ::=
"1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
hexadecimal-prefix ::=
"0x" | "0X"
hexadecimal-digit-sequence ::=
hexadecimal-digit
| hexadecimal-digit-sequence "'"? hexadecimal-digit
hexadecimal-digit ::=
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
| "a" | "b" | "c" | "d" | "e" | "f"
| "A" | "B" | "C" | "D" | "E" | "F"
integer-suffix ::=
unsigned-suffix long-suffix?
| unsigned-suffix long-long-suffix?
| unsigned-suffix size-suffix?
| long-suffix unsigned-suffix?
| long-long-suffix unsigned-suffix?
| size-suffix unsigned-suffix?
unsigned-suffix ::=
"u" | "U"
long-suffix ::=
"l" | "L"
long-long-suffix ::=
"ll" | "LL"
size-suffix ::=
"z" | "Z"
character-literal ::=
encoding-prefix? "'" c-char-sequence "'"
encoding-prefix ::=
"u8" | "u" | "U" | "L"
c-char-sequence ::=
c-char
| c-char-sequence c-char
c-char ::=
basic-c-char
| escape-sequence
| universal-character-name
basic-c-char ::=
"{any member of the translation character set except the \unicode{0027}{apostrophe},}"
"{\unicode{005c}{reverse solidus}, or new-line character}"
escape-sequence ::=
simple-escape-sequence
| numeric-escape-sequence
| conditional-escape-sequence
simple-escape-sequence ::=
"\" simple-escape-sequence-char
simple-escape-sequence-char ::=
"'" | '"' | "?" | "\" | "a" | "b" | "f" | "n" | "r" | "t" | "v"
numeric-escape-sequence ::=
octal-escape-sequence
| hexadecimal-escape-sequence
simple-octal-digit-sequence ::=
octal-digit
| simple-octal-digit-sequence octal-digit
octal-escape-sequence ::=
"\" octal-digit
| "\" octal-digit octal-digit
| "\" octal-digit octal-digit octal-digit
| "\o{" simple-octal-digit-sequence "}"
hexadecimal-escape-sequence ::=
"\x" simple-hexadecimal-digit-sequence
| "\x{" simple-hexadecimal-digit-sequence "}"
conditional-escape-sequence ::=
"\" conditional-escape-sequence-char
conditional-escape-sequence-char ::=
'{any member of the basic character set that is not an octal-digit, a simple-escape-sequence-char, or the characters "N", "o", "u", "U", or "x"}'
floating-point-literal ::=
decimal-floating-point-literal
| hexadecimal-floating-point-literal
decimal-floating-point-literal ::=
fractional-constant exponent-part? floating-point-suffix?
| digit-sequence exponent-part floating-point-suffix?
hexadecimal-floating-point-literal ::=
hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-point-suffix?
| hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-point-suffix?
fractional-constant ::=
digit-sequence? "." digit-sequence
| digit-sequence "."
hexadecimal-fractional-constant ::=
hexadecimal-digit-sequence? "." hexadecimal-digit-sequence
| hexadecimal-digit-sequence "."
exponent-part ::=
"e" sign? digit-sequence
| "E" sign? digit-sequence
binary-exponent-part ::=
"p" sign? digit-sequence
| "P" sign? digit-sequence
sign ::=
"+" | "-"
digit-sequence ::=
digit
| digit-sequence "'"? digit
floating-point-suffix ::=
"f" | "l" | "f16" | "f32" | "f64" | "f128" | "bf16" | "F" | "L" | "F16" | "F32" | "F64" | "F128" | "BF16"
string-literal ::=
encoding-prefix? '"' s-char-sequence? '"'
| encoding-prefix? "R" raw-string
s-char-sequence ::=
s-char
| s-char-sequence s-char
s-char ::=
basic-s-char
| escape-sequence
| universal-character-name
basic-s-char ::=
"{any member of the translation character set except the \unicode{0022}{quotation mark},}"
"{\unicode{005c}{reverse solidus}, or new-line character}"
raw-string ::=
'"' d-char-sequence? "(" r-char-sequence? ")" d-char-sequence? '"'
r-char-sequence ::=
r-char
| r-char-sequence r-char
r-char ::=
"{any member of the translation character set, except a \unicode{0029}{right parenthesis} followed by}"
"{the initial d-char-sequence (which may be empty) followed by a \unicode{0022}{quotation mark}}"
d-char-sequence ::=
d-char
| d-char-sequence d-char
d-char ::=
"{any member of the basic character set except:}"
"{\unicode{0020}{space}, \unicode{0028}{left parenthesis}, \unicode{0029}{right parenthesis}, \unicode{005c}{reverse solidus},}"
"{\unicode{0009}{character tabulation}, \unicode{000b}{line tabulation}, \unicode{000c}{form feed}, and new-line}"
unevaluated-string ::=
string-literal
boolean-literal ::=
"false"
| "true"
pointer-literal ::=
"nullptr"
user-defined-literal ::=
user-defined-integer-literal
| user-defined-floating-point-literal
| user-defined-string-literal
| user-defined-character-literal
user-defined-integer-literal ::=
decimal-literal ud-suffix
| octal-literal ud-suffix
| hexadecimal-literal ud-suffix
| binary-literal ud-suffix
user-defined-floating-point-literal ::=
fractional-constant exponent-part? ud-suffix
| digit-sequence exponent-part ud-suffix
| hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix
| hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix
user-defined-string-literal ::=
string-literal ud-suffix
user-defined-character-literal ::=
character-literal ud-suffix
ud-suffix ::=
identifier
//== basic.tex
translation-unit ::=
declaration-seq?
| global-module-fragment? module-declaration declaration-seq? private-module-fragment?
//== expressions.tex
primary-expression ::=
literal
| "this"
| "(" expression ")"
| id-expression
| lambda-expression
| fold-expression
| requires-expression
id-expression ::=
unqualified-id
| qualified-id
| pack-index-expression
unqualified-id ::=
identifier
| operator-function-id
| conversion-function-id
| literal-operator-id
| "~" type-name
| "~" computed-type-specifier
| template-id
qualified-id ::=
nested-name-specifier "template"? unqualified-id
nested-name-specifier ::=
"::"
| type-name "::"
| namespace-name "::"
| computed-type-specifier "::"
| nested-name-specifier identifier "::"
| nested-name-specifier "template"? simple-template-id "::"
pack-index-expression ::=
id-expression "..." "[" constant-expression "]"
lambda-expression ::=
lambda-introducer attribute-specifier-seq? lambda-declarator compound-statement
| lambda-introducer "<" template-parameter-list ">" requires-clause? attribute-specifier-seq?
lambda-declarator compound-statement
lambda-introducer ::=
"[" lambda-capture? "]"
lambda-declarator ::=
lambda-specifier-seq noexcept-specifier? attribute-specifier-seq? trailing-return-type?
| noexcept-specifier attribute-specifier-seq? trailing-return-type?
| trailing-return-type?
| "(" parameter-declaration-clause ")" lambda-specifier-seq? noexcept-specifier? attribute-specifier-seq?
trailing-return-type? requires-clause?
lambda-specifier ::=
"consteval"
| "constexpr"
| "mutable"
| "static"
lambda-specifier-seq ::=
lambda-specifier
| lambda-specifier lambda-specifier-seq
lambda-capture ::=
capture-default
| capture-list
| capture-default "," capture-list
capture-default ::=
"&"
| "="
capture-list ::=
capture
| capture-list "," capture
capture ::=
simple-capture
| init-capture
simple-capture ::=
identifier "..."?
| "&" identifier "..."?
| "this"
| "*" "this"
init-capture ::=
"..."? identifier initializer
| "&" "..."? identifier initializer
fold-expression ::=
"(" cast-expression fold-operator "..." ")"
| "(" "..." fold-operator cast-expression ")"
| "(" cast-expression fold-operator "..." fold-operator cast-expression ")"
fold-operator ::=
"+" | "-" | "*" | "/" | "%" | "^" | "&" | "|" | "<<" | ">>"
| "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&=" | "|=" | "<<=" | ">>=" | "="
| "==" | "!=" | "<" | ">" | "<=" | ">=" | "&&" | "||" | "," | ".*" | "->*"
requires-expression ::=
"requires" requirement-parameter-list? requirement-body
requirement-parameter-list ::=
"(" parameter-declaration-clause ")"
requirement-body ::=
"{" requirement-seq "}"
requirement-seq ::=
requirement
| requirement requirement-seq
requirement ::=
simple-requirement
| type-requirement
| compound-requirement
| nested-requirement
simple-requirement ::=
expression ";"
type-requirement ::=
"typename" nested-name-specifier? type-name ";"
compound-requirement ::=
"{" expression "}" "noexcept"? return-type-requirement? ";"
return-type-requirement ::=
"->" type-constraint
nested-requirement ::=
"requires" constraint-expression ";"
postfix-expression ::=
primary-expression
| postfix-expression "[" expression-list? "]"
| postfix-expression "(" expression-list? ")"
| simple-type-specifier "(" expression-list? ")"
| typename-specifier "(" expression-list? ")"
| simple-type-specifier braced-init-list
| typename-specifier braced-init-list
| postfix-expression "." "template"? id-expression
| postfix-expression "->" "template"? id-expression
| 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 ::=
initializer-list
unary-expression ::=
postfix-expression
| unary-operator cast-expression
| "++" cast-expression
| "--" cast-expression
| await-expression
| "sizeof" unary-expression
| "sizeof" "(" type-id ")"
| "sizeof" "..." "(" identifier ")"
| "alignof" "(" type-id ")"
| noexcept-expression
| new-expression
| delete-expression
unary-operator ::=
"*" | "&" | "+" | "-" | "!" | "~"
await-expression ::=
"co_await" cast-expression
noexcept-expression ::=
"noexcept" "(" expression ")"
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?
| noptr-new-declarator
noptr-new-declarator ::=
"[" expression? "]" attribute-specifier-seq?
| noptr-new-declarator "[" constant-expression "]" attribute-specifier-seq?
new-initializer ::=
"(" expression-list? ")"
| braced-init-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
compare-expression ::=
shift-expression
| compare-expression "<=>" shift-expression
relational-expression ::=
compare-expression
| relational-expression "<" compare-expression
| relational-expression ">" compare-expression
| relational-expression "<=" compare-expression
| relational-expression ">=" compare-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
yield-expression ::=
"co_yield" assignment-expression
| "co_yield" braced-init-list
throw-expression ::=
"throw" assignment-expression?
assignment-expression ::=
conditional-expression
| yield-expression
| throw-expression
| logical-or-expression assignment-operator initializer-clause
assignment-operator ::=
"=" | "*=" | "/=" | "%=" | "+=" | "-=" | ">>=" | "<<=" | "&=" | "^=" | "|="
expression ::=
assignment-expression
| expression "," assignment-expression
constant-expression ::=
conditional-expression
//== statements.tex
statement ::=
labeled-statement
| attribute-specifier-seq? expression-statement
| attribute-specifier-seq? compound-statement
| attribute-specifier-seq? selection-statement
| attribute-specifier-seq? iteration-statement
| attribute-specifier-seq? jump-statement
| declaration-statement
| attribute-specifier-seq? try-block
init-statement ::=
expression-statement
| simple-declaration
| alias-declaration
condition ::=
expression
| attribute-specifier-seq? decl-specifier-seq declarator brace-or-equal-initializer
label ::=
attribute-specifier-seq? identifier ":"
| attribute-specifier-seq? "case" constant-expression ":"
| attribute-specifier-seq? "default" ":"
labeled-statement ::=
label statement
expression-statement ::=
expression? ";"
compound-statement ::=
"{" statement-seq? label-seq? "}"
statement-seq ::=
statement
| statement-seq statement
label-seq ::=
label
| label-seq label
selection-statement ::=
"if" "constexpr"? "(" init-statement? condition ")" statement
| "if" "constexpr"? "(" init-statement? condition ")" statement "else" statement
| "if" "!"? "consteval" compound-statement
| "if" "!"? "consteval" compound-statement "else" statement
| "switch" "(" init-statement? condition ")" statement
iteration-statement ::=
"while" "(" condition ")" statement
| "do" statement "while" "(" expression ")" ";"
| "for" "(" init-statement condition? ";" expression? ")" statement
| "for" "(" init-statement? for-range-declaration ":" for-range-initializer ")" statement
for-range-declaration ::=
attribute-specifier-seq? decl-specifier-seq declarator
| attribute-specifier-seq? decl-specifier-seq ref-qualifier? "[" identifier-list "]"
for-range-initializer ::=
expr-or-braced-init-list
jump-statement ::=
"break" ";"
| "continue" ";"
| "return" expr-or-braced-init-list? ";"
| coroutine-return-statement
| "goto" identifier ";"
coroutine-return-statement ::=
"co_return" expr-or-braced-init-list? ";"
declaration-statement ::=
block-declaration
//== declarations.tex
declaration-seq ::=
declaration
| declaration-seq declaration
declaration ::=
name-declaration
| special-declaration
name-declaration ::=
block-declaration
| nodeclspec-function-declaration
| function-definition
| template-declaration
| deduction-guide
| linkage-specification
| namespace-definition
| empty-declaration
| attribute-declaration
| module-import-declaration
special-declaration ::=
explicit-instantiation
| explicit-specialization
| export-declaration
block-declaration ::=
simple-declaration
| asm-declaration
| namespace-alias-definition
| using-declaration
| using-enum-declaration
| using-directive
| static_assert-declaration
| alias-declaration
| opaque-enum-declaration
nodeclspec-function-declaration ::=
attribute-specifier-seq? declarator ";"
alias-declaration ::=
"using" identifier attribute-specifier-seq? "=" defining-type-id ";"
simple-declaration ::=
decl-specifier-seq init-declarator-list? ";"
| attribute-specifier-seq decl-specifier-seq init-declarator-list ";"
| attribute-specifier-seq? decl-specifier-seq ref-qualifier? "[" identifier-list "]" initializer ";"
static_assert-message ::=
unevaluated-string
| constant-expression
static_assert-declaration ::=
"static_assert" "(" constant-expression ")" ";"
| "static_assert" "(" constant-expression "," static_assert-message ")" ";"
empty-declaration ::=
";"
attribute-declaration ::=
attribute-specifier-seq ";"
decl-specifier ::=
storage-class-specifier
| defining-type-specifier
| function-specifier
| "friend"
| "typedef"
| "constexpr"
| "consteval"
| "constinit"
| "inline"
decl-specifier-seq ::=
decl-specifier attribute-specifier-seq?
| decl-specifier decl-specifier-seq
storage-class-specifier ::=
"static"
| "thread_local"
| "extern"
| "mutable"
function-specifier ::=
"virtual"
| explicit-specifier
explicit-specifier ::=
"explicit" "(" constant-expression ")"
| "explicit"
typedef-name ::=
identifier
| simple-template-id
type-specifier ::=
simple-type-specifier
| elaborated-type-specifier
| typename-specifier
| cv-qualifier
type-specifier-seq ::=
type-specifier attribute-specifier-seq?
| type-specifier type-specifier-seq
defining-type-specifier ::=
type-specifier
| class-specifier
| enum-specifier
defining-type-specifier-seq ::=
defining-type-specifier attribute-specifier-seq?
| defining-type-specifier defining-type-specifier-seq
simple-type-specifier ::=
nested-name-specifier? type-name
| nested-name-specifier "template" simple-template-id
| computed-type-specifier
| placeholder-type-specifier
| nested-name-specifier? template-name
| "char"
| "char8_t"
| "char16_t"
| "char32_t"
| "wchar_t"
| "bool"
| "short"
| "int"
| "long"
| "signed"
| "unsigned"
| "float"
| "double"
| "void"
type-name ::=
class-name
| enum-name
| typedef-name
computed-type-specifier ::=
decltype-specifier
| pack-index-specifier
pack-index-specifier ::=
typedef-name "..." "[" constant-expression "]"
elaborated-type-specifier ::=
class-key attribute-specifier-seq? nested-name-specifier? identifier
| class-key simple-template-id
| class-key nested-name-specifier "template"? simple-template-id
| "enum" nested-name-specifier? identifier
decltype-specifier ::=
"decltype" "(" expression ")"
placeholder-type-specifier ::=
type-constraint? "auto"
| type-constraint? "decltype" "(" "auto" ")"
init-declarator-list ::=
init-declarator
| init-declarator-list "," init-declarator
init-declarator ::=
declarator initializer?
| declarator requires-clause
declarator ::=
ptr-declarator
| noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator ::=
noptr-declarator
| ptr-operator ptr-declarator
noptr-declarator ::=
declarator-id attribute-specifier-seq?
| noptr-declarator parameters-and-qualifiers
| noptr-declarator "[" constant-expression? "]" attribute-specifier-seq?
| "(" ptr-declarator ")"
parameters-and-qualifiers ::=
"(" parameter-declaration-clause ")" cv-qualifier-seq?
ref-qualifier? noexcept-specifier? attribute-specifier-seq?
trailing-return-type ::=
"->" type-id
ptr-operator ::=
"*" attribute-specifier-seq? cv-qualifier-seq?
| "&" attribute-specifier-seq?
| "&&" attribute-specifier-seq?
| nested-name-specifier "*" attribute-specifier-seq? cv-qualifier-seq?
cv-qualifier-seq ::=
cv-qualifier cv-qualifier-seq?
cv-qualifier ::=
"const"
| "volatile"
ref-qualifier ::=
"&"
| "&&"
declarator-id ::=
"..."? id-expression
type-id ::=
type-specifier-seq abstract-declarator?
defining-type-id ::=
defining-type-specifier-seq abstract-declarator?
abstract-declarator ::=
ptr-abstract-declarator
| noptr-abstract-declarator? parameters-and-qualifiers trailing-return-type
| abstract-pack-declarator
ptr-abstract-declarator ::=
noptr-abstract-declarator
| ptr-operator ptr-abstract-declarator?
noptr-abstract-declarator ::=
noptr-abstract-declarator? parameters-and-qualifiers
| noptr-abstract-declarator? "[" constant-expression? "]" attribute-specifier-seq?
| "(" ptr-abstract-declarator ")"
abstract-pack-declarator ::=
noptr-abstract-pack-declarator
| ptr-operator abstract-pack-declarator
noptr-abstract-pack-declarator ::=
noptr-abstract-pack-declarator parameters-and-qualifiers
| "..."
parameter-declaration-clause ::=
parameter-declaration-list? "..."?
| parameter-declaration-list "," "..."
parameter-declaration-list ::=
parameter-declaration
| parameter-declaration-list "," parameter-declaration
parameter-declaration ::=
attribute-specifier-seq? "this"? decl-specifier-seq declarator
| attribute-specifier-seq? decl-specifier-seq declarator "=" initializer-clause
| attribute-specifier-seq? "this"? decl-specifier-seq abstract-declarator?
| attribute-specifier-seq? decl-specifier-seq abstract-declarator? "=" initializer-clause
initializer ::=
brace-or-equal-initializer
| "(" expression-list ")"
brace-or-equal-initializer ::=
"=" initializer-clause
| braced-init-list
initializer-clause ::=
assignment-expression
| braced-init-list
braced-init-list ::=
"{" initializer-list ","? "}"
| "{" designated-initializer-list ","? "}"
| "{" "}"
initializer-list ::=
initializer-clause "..."?
| initializer-list "," initializer-clause "..."?
designated-initializer-list ::=
designated-initializer-clause
| designated-initializer-list "," designated-initializer-clause
designated-initializer-clause ::=
designator brace-or-equal-initializer
designator ::=
"." identifier
expr-or-braced-init-list ::=
expression
| braced-init-list
function-definition ::=
attribute-specifier-seq? decl-specifier-seq? declarator virt-specifier-seq? function-body
| attribute-specifier-seq? decl-specifier-seq? declarator requires-clause function-body
function-body ::=
ctor-initializer? compound-statement
| function-try-block
| "=" "default" ";"
| "=" "delete" ";"
enum-name ::=
identifier
enum-specifier ::=
enum-head "{" enumerator-list? "}"
| enum-head "{" enumerator-list "," "}"
enum-head ::=
enum-key attribute-specifier-seq? enum-head-name? enum-base?
enum-head-name ::=
nested-name-specifier? identifier
opaque-enum-declaration ::=
enum-key attribute-specifier-seq? enum-head-name enum-base? ";"
enum-key ::=
"enum"
| "enum" "class"
| "enum" "struct"
enum-base ::=
":" type-specifier-seq
enumerator-list ::=
enumerator-definition
| enumerator-list "," enumerator-definition
enumerator-definition ::=
enumerator
| enumerator "=" constant-expression
enumerator ::=
identifier attribute-specifier-seq?
using-enum-declaration ::=
"using" "enum" using-enum-declarator ";"
using-enum-declarator ::=
nested-name-specifier? identifier
| nested-name-specifier? simple-template-id
namespace-name ::=
identifier
| namespace-alias
namespace-definition ::=
named-namespace-definition
| unnamed-namespace-definition
| nested-namespace-definition
named-namespace-definition ::=
"inline"? "namespace" attribute-specifier-seq? identifier "{" namespace-body "}"
unnamed-namespace-definition ::=
"inline"? "namespace" attribute-specifier-seq? "{" namespace-body "}"
nested-namespace-definition ::=
"namespace" enclosing-namespace-specifier "::" "inline"? identifier "{" namespace-body "}"
enclosing-namespace-specifier ::=
identifier
| enclosing-namespace-specifier "::" "inline"? identifier
namespace-body ::=
declaration-seq?
namespace-alias ::=
identifier
namespace-alias-definition ::=
"namespace" identifier "=" qualified-namespace-specifier ";"
qualified-namespace-specifier ::=
nested-name-specifier? namespace-name
using-directive ::=
attribute-specifier-seq? "using" "namespace" nested-name-specifier? namespace-name ";"
using-declaration ::=
"using" using-declarator-list ";"
using-declarator-list ::=
using-declarator "..."?
| using-declarator-list "," using-declarator "..."?
using-declarator ::=
"typename"? nested-name-specifier unqualified-id
asm-declaration ::=
attribute-specifier-seq? "asm" "(" balanced-token-seq ")" ";"
linkage-specification ::=
"extern" unevaluated-string "{" declaration-seq? "}"
| "extern" unevaluated-string name-declaration
attribute-specifier-seq ::=
attribute-specifier-seq? attribute-specifier
attribute-specifier ::=
"[" "[" attribute-using-prefix? attribute-list "]" "]"
| alignment-specifier
alignment-specifier ::=
"alignas" "(" type-id "..."? ")"
| "alignas" "(" constant-expression "..."? ")"
attribute-using-prefix ::=
"using" attribute-namespace ":"
attribute-list ::=
attribute?
| attribute-list "," attribute?
| attribute "..."
| attribute-list "," attribute "..."
attribute ::=
attribute-token attribute-argument-clause?
attribute-token ::=
identifier
| attribute-scoped-token
attribute-scoped-token ::=
attribute-namespace "::" identifier
attribute-namespace ::=
identifier
attribute-argument-clause ::=
"(" balanced-token-seq? ")"
balanced-token-seq ::=
balanced-token
| balanced-token-seq balanced-token
balanced-token ::=
"(" balanced-token-seq? ")"
| "[" balanced-token-seq? "]"
| "{" balanced-token-seq? "}"
| "{any token other than a parenthesis, a bracket, or a brace}"
//== modules.tex
module-declaration ::=
"export"? "module" module-name module-partition? attribute-specifier-seq? ";"
module-name ::=
module-name-qualifier? identifier
module-partition ::=
":" module-name-qualifier? identifier
module-name-qualifier ::=
identifier "."
| module-name-qualifier identifier "."
export-declaration ::=
"export" name-declaration
| "export" "{" declaration-seq? "}"
| "export" module-import-declaration
module-import-declaration ::=
"import" module-name attribute-specifier-seq? ";"
| "import" module-partition attribute-specifier-seq? ";"
| "import" header-name attribute-specifier-seq? ";"
global-module-fragment ::=
"module" ";" declaration-seq?
private-module-fragment ::=
"module" ":" "private" ";" declaration-seq?
//== classes.tex
class-name ::=
identifier
| simple-template-id
class-specifier ::=
class-head "{" member-specification? "}"
class-head ::=
class-key attribute-specifier-seq? class-head-name class-virt-specifier? base-clause?
| class-key attribute-specifier-seq? base-clause?
class-head-name ::=
nested-name-specifier? class-name
class-virt-specifier ::=
"final"
class-key ::=
"class"
| "struct"
| "union"
member-specification ::=
member-declaration member-specification?
| access-specifier ":" member-specification?
member-declaration ::=
attribute-specifier-seq? decl-specifier-seq? member-declarator-list? ";"
| function-definition
| using-declaration
| using-enum-declaration
| static_assert-declaration
| template-declaration
| explicit-specialization
| deduction-guide
| alias-declaration
| opaque-enum-declaration
| empty-declaration
member-declarator-list ::=
member-declarator
| member-declarator-list "," member-declarator
member-declarator ::=
declarator virt-specifier-seq? pure-specifier?
| declarator requires-clause
| declarator brace-or-equal-initializer?
| identifier? attribute-specifier-seq? ":" constant-expression brace-or-equal-initializer?
virt-specifier-seq ::=
virt-specifier
| virt-specifier-seq virt-specifier
virt-specifier ::=
"override"
| "final"
pure-specifier ::=
"=" "0"
conversion-function-id ::=
"operator" conversion-type-id
conversion-type-id ::=
type-specifier-seq conversion-declarator?
conversion-declarator ::=
ptr-operator conversion-declarator?
base-clause ::=
":" base-specifier-list
base-specifier-list ::=
base-specifier "..."?
| base-specifier-list "," base-specifier "..."?
base-specifier ::=
attribute-specifier-seq? class-or-decltype
| attribute-specifier-seq? "virtual" access-specifier? class-or-decltype
| attribute-specifier-seq? access-specifier "virtual"? class-or-decltype
class-or-decltype ::=
nested-name-specifier? type-name
| nested-name-specifier "template" simple-template-id
| decltype-specifier
access-specifier ::=
"private"
| "protected"
| "public"
ctor-initializer ::=
":" mem-initializer-list
mem-initializer-list ::=
mem-initializer "..."?
| mem-initializer-list "," mem-initializer "..."?
mem-initializer ::=
mem-initializer-id "(" expression-list? ")"
| mem-initializer-id braced-init-list
mem-initializer-id ::=
class-or-decltype
| identifier
//== overloading.tex
operator-function-id ::=
"operator" operator
operator ::=
"new" | "delete" | "new[]" | "delete[]" | "co_await" | "()" | "[]" | "->" | "->*"
| "~" | "!" | "+" | "-" | "*" | "/" | "%" | "^" | "&"
| "|" | "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "^=" | "&="
| "|=" | "==" | "!=" | "<" | ">" | "<=" | ">=" | "<=>" | "&&"
| "||" | "<<" | ">>" | "<<=" | ">>=" | "++" | "--" | ","
literal-operator-id ::=
"operator" unevaluated-string identifier
| "operator" user-defined-string-literal
//== templates.tex
template-declaration ::=
template-head declaration
| template-head concept-definition
template-head ::=
"template" "<" template-parameter-list ">" requires-clause?
template-parameter-list ::=
template-parameter
| template-parameter-list "," template-parameter
requires-clause ::=
"requires" constraint-logical-or-expression
constraint-logical-or-expression ::=
constraint-logical-and-expression
| constraint-logical-or-expression "||" constraint-logical-and-expression
constraint-logical-and-expression ::=
primary-expression
| constraint-logical-and-expression "&&" primary-expression
template-parameter ::=
type-parameter
| parameter-declaration
type-parameter ::=
type-parameter-key "..."? identifier?
| type-parameter-key identifier? "=" type-id
| type-constraint "..."? identifier?
| type-constraint identifier? "=" type-id
| template-head type-parameter-key "..."? identifier?
| template-head type-parameter-key identifier? "=" id-expression
type-parameter-key ::=
"class"
| "typename"
type-constraint ::=
nested-name-specifier? concept-name
| nested-name-specifier? concept-name "<" template-argument-list? ">"
simple-template-id ::=
template-name "<" template-argument-list? ">"
template-id ::=
simple-template-id
| operator-function-id "<" template-argument-list? ">"
| literal-operator-id "<" template-argument-list? ">"
template-name ::=
identifier
template-argument-list ::=
template-argument "..."?
| template-argument-list "," template-argument "..."?
template-argument ::=
constant-expression
| type-id
| id-expression
| braced-init-list
constraint-expression ::=
logical-or-expression
deduction-guide ::=
explicit-specifier? template-name "(" parameter-declaration-clause ")" "->" simple-template-id ";"
concept-definition ::=
"concept" concept-name attribute-specifier-seq? "=" constraint-expression ";"
concept-name ::=
identifier
typename-specifier ::=
"typename" nested-name-specifier identifier
| "typename" nested-name-specifier "template"? simple-template-id
explicit-instantiation ::=
"extern"? "template" declaration
explicit-specialization ::=
"template" "<" ">" declaration
//== exceptions.tex
try-block ::=
"try" compound-statement handler-seq
function-try-block ::=
"try" ctor-initializer? compound-statement handler-seq
handler-seq ::=
handler handler-seq?
handler ::=
"catch" "(" exception-declaration ")" compound-statement
exception-declaration ::=
attribute-specifier-seq? type-specifier-seq declarator
| attribute-specifier-seq? type-specifier-seq abstract-declarator?
| "..."
noexcept-specifier ::=
"noexcept" "(" constant-expression ")"
| "noexcept"
//== preprocessor.tex
preprocessing-file ::=
group?
| module-file
module-file ::=
pp-global-module-fragment? pp-module group? pp-private-module-fragment?
pp-global-module-fragment ::=
"module" ";" new-line group?
pp-private-module-fragment ::=
"module" ":" "private" ";" new-line group?
group ::=
group-part
| group group-part
group-part ::=
control-line
| if-section
| text-line
| "#" conditionally-supported-directive
control-line ::=
"#" "include" pp-tokens new-line
| pp-import
| "#" "define" identifier replacement-list new-line
| "#" "define" identifier lparen identifier-list? ")" replacement-list new-line
| "#" "define" identifier lparen "..." ")" 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
| "#" "warning" pp-tokens? new-line
| "#" "pragma" pp-tokens? new-line
| "#" new-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?
| "#" "elifdef" identifier new-line group?
| "#" "elifndef" identifier new-line group?
else-group ::=
"#" "else" new-line group?
endif-line ::=
"#" "endif" new-line
text-line ::=
pp-tokens? new-line
conditionally-supported-directive ::=
pp-tokens new-line
lparen ::=
'{a "(" character not immediately preceded by whitespace}'
identifier-list ::=
identifier
| identifier-list "," identifier
replacement-list ::=
pp-tokens?
pp-tokens ::=
preprocessing-token
| pp-tokens preprocessing-token
new-line ::=
"{the new-line character}"
defined-macro-expression ::=
"defined" identifier
| "defined" "(" identifier ")"
h-preprocessing-token ::=
'{any preprocessing-token other than ">"}'
h-pp-tokens ::=
h-preprocessing-token
| h-pp-tokens h-preprocessing-token
header-name-tokens ::=
string-literal
| "<" h-pp-tokens ">"
has-include-expression ::=
"has_include" "(" header-name ")"
| "has_include" "(" header-name-tokens ")"
has-attribute-expression ::=
"has_cpp_attribute" "(" pp-tokens ")"
pp-module ::=
"export"? "module" pp-tokens? ";" new-line
pp-import ::=
"export"? "import" header-name pp-tokens? ";" new-line
| "export"? "import" header-name-tokens pp-tokens? ";" new-line
| "export"? "import" pp-tokens ";" new-line
va-opt-replacement ::=
"VA_OPT" "(" pp-tokens? ")"
Using the EBNF syntax to also give a high level view for the actual parser (not finished):
//
// EBNF to be viewd at https://www.bottlecaps.de/rr/ui
//
// Copy and paste this at https://www.bottlecaps.de/rr/ui in the 'Edit Grammar' tab
// then click the 'View Diagram' tab.
//
parse_translation_unit ::=
parse_module_unit
| parse_top_level_declaration_seq
parse_module_unit ::=
parse_module_head parse_global_module_fragment
parse_module_declaration parse_declaration_seq parse_private_module_fragment
parse_top_level_declaration_seq ::=
parse_declaration+
parse_declaration_seq ::=
parse_maybe_module
| parse_declaration+
parse_declaration ::=
parse_empty_declaration
| parse_explicit_instantiation
| parse_template_declaration
| parse_linkage_specification
| parse_namespace_definition
| parse_deduction_guide
| parse_export_declaration
| parse_module_import_declaration
| parse_attribute_declaration
| parse_block_declaration
parse_empty_declaration ::=
T_SEMICOLON
parse_explicit_instantiation ::=
T_EXTERN T_TEMPLATE parse_declaration
parse_template_declaration ::=
T_TEMPLATE T_LESS parse_template_parameter_list T_GREATER
parse_requires_clause parse_template_declaration?
parse_concept_definition?
parse_template_declaration_body
parse_linkage_specification ::=
T_EXTERN parse_optional_attribute_specifier_seq T_STRING_LITERAL
(T_LBRACE parse_declaration_seq T_RBRACE | parse_declaration )
parse_namespace_definition ::=
T_INLINE? T_NAMESPACE parse_optional_attribute_specifier_seq T_IDENTIFIER T_COLON_COLON
parse_namespace_body
parse_deduction_guide ::=
parse_explicit_specifier T_IDENTIFIER T_LPAREN parse_parameter_declaration_clause T_RPAREN
parse_simple_template_id T_SEMICOLON
parse_export_declaration ::=
T_EXPORT (T_LBRACE parse_declaration_seq T_RBRACE | parse_module_import_declaration? parse_declaration )
parse_module_import_declaration ::=
parse_import_keyword parse_import_name parse_optional_attribute_specifier_seq T_SEMICOLON
parse_attribute_declaration ::=
parse_attribute_specifier_seq T_SEMICOLON
parse_block_declaration ::=
parse_asm_declaration
| parse_namespace_alias_definition
| parse_static_assert_declaration
| parse_opaque_enum_declaration
| parse_using_enum_declaration
| parse_using_directive
| parse_alias_declaration
| parse_using_declaration
| parse_simple_declaration
parse_asm_declaration ::=
T_ASM AsmQualifier* T_LPAREN T_STRING_LITERAL
AsmOutputOperandList? AsmInpputOperandList?
T_RPAREN T_SEMICOLON
AsmQualifier ::=
T_INLINE
| T_VOLATILE
| T_GOTO
AsmOutputOperandList ::=
AsmInOutOperandList
AsmInpputOperandList ::=
AsmInOutOperandList
AsmInOutOperandList ::=
T_COLON parse_asm_operand (T_COMMA parse_asm_operand)*
parse_namespace_alias_definition ::=
T_NAMESPACE T_IDENTIFIER T_EQUAL parse_qualified_namespace_specifier T_SEMICOLON
parse_static_assert_declaration ::=
T_STATIC_ASSERT T_LPAREN parse_constant_expression (T_COMMA T_STRING_LITERAL)? T_RPAREN T_SEMICOLON
parse_opaque_enum_declaration ::=
parse_optional_attribute_specifier_seq parse_enum_key parse_enum_head_name parse_enum_base T_SEMICOLON
parse_using_enum_declaration ::=
T_USING parse_elaborated_enum_specifier T_SEMICOLON
parse_using_directive ::=
T_USING T_NAMESPACE parse_optional_nested_name_specifier parse_name_id T_SEMICOLON
parse_alias_declaration ::=
T_USING T_IDENTIFIER parse_optional_attribute_specifier_seq T_EQUAL parse_defining_type_id T_SEMICOLON
parse_using_declaration ::=
T_USING parse_using_declarator_list T_SEMICOLON
parse_simple_declaration ::=
parse_one_simple_declaration+
parse_one_simple_declaration ::=
T___EXTENSION__? parse_optional_attribute_specifier_seq
(
T_SEMICOLON
| parse_template_class_declaration
| parse_empty_or_attribute_declaration
| parse_notypespec_function_definition
| parse_decl_specifier_seq
| parse_type_or_forward_declaration
| parse_structured_binding
)
parse_module_head ::=
T_EXPORT parse_id
parse_global_module_fragment ::=
parse_module_keyword T_SEMICOLON parse_declaration_seq
parse_module_declaration ::=
parse_export_keyword parse_module_keyword parse_module_name parse_module_partition
parse_optional_attribute_specifier_seq T_SEMICOLON
parse_private_module_fragment ::=
parse_module_keyword T_COLON T_PRIVATE T_SEMICOLON parse_declaration_seq
parse_block_declaration ::=
parse_class_specifier parse_attribute_specifier_seq T_SEMICOLON
parse_class_specifier ::=
parse_class_head T_LBRACE parse_class_body T_RBRACE
parse_class_head ::=
(T_CLASS | T_STRUCT | T_UNION) parse_optional_attribute_specifier_seq
parse_class_head_name parse_class_virt_specifier parse_base_clause
parse_class_head_name ::=
parse_optional_nested_name_specifier check_type_traits parse_type_name
parse_class_virt_specifier ::=
parse_final
parse_base_clause ::=
T_COLON parse_base_specifier_list
parse_base_specifier_list ::=
parse_base_specifier T_DOT_DOT_DOT ( T_COMMA parse_base_specifier T_DOT_DOT_DOT)*
parse_base_specifier ::=
parse_optional_attribute_specifier_seq
(T_VIRTUAL parse_access_specifier | parse_access_specifier T_VIRTUAL)?
parse_class_or_decltype
parse_class_body ::=
parse_member_specification*
parse_member_specification ::=
parse_member_declaration
parse_member_declaration ::=
parse_access_specifier T_COLON
| parse_empty_declaration
| parse_using_enum_declaration
| parse_alias_declaration
| parse_using_declaration
| parse_static_assert_declaration
| parse_deduction_guide
| parse_opaque_enum_declaration
| parse_template_declaration
| parse_member_declaration_helper
parse_member_declaration_helper ::=
T___EXTENSION__? parse_optional_attribute_specifier_seq parse_decl_specifier_seq_no_typespecs
(parse_notypespec_function_definition | parse_decl_specifier_seq T_SEMICOLON )
parse_notypespec_function_definition ::=
parse_declarator_id parse_function_declarator parse_requires_clause parse_virt_specifier_seq
parse_optional_attribute_specifier_seq parse_pure_specifier (T_SEMICOLON | parse_function_body)
parse_function_body ::=
parse_function_try_block
| T_EQUAL T_DEFAULT T_SEMICOLON
| T_EQUAL T_DELETE T_SEMICOLON
| parse_ctor_initializer parse_compound_statement
parse_compound_statement ::=
T_LBRACE finish_compound_statement? T_RBRACE
finish_compound_statement ::=
( parse_maybe_statement | parse_skip_statement )+
parse_maybe_statement ::=
T___EXTENSION__? (
parse_case_statement
| parse_default_statement
| parse_while_statement
| parse_do_statement
| parse_for_statement
| parse_if_statement
| parse_switch_statement
| parse_break_statement
| parse_continue_statement
| parse_return_statement
| parse_goto_statement
| parse_coroutine_return_statement
| parse_try_block
| parse_maybe_compound_statement
| parse_labeled_statement
| parse_declaration_statement
| parse_expression_statement
)
parse_case_statement ::=
T_CASE parse_constant_expression T_COLON
parse_default_statement ::=
T_DEFAULT T_COLON
parse_while_statement ::=
T_WHILE T_LPAREN parse_condition T_RPAREN
parse_do_statement ::=
T_DO parse_statement T_WHILE T_LPAREN parse_expression T_RPAREN T_SEMICOLON
parse_for_statement ::=
parse_for_range_statement
| T_FOR T_LPAREN parse_init_statement T_SEMICOLON parse_condition T_SEMICOLON parse_expression T_RPAREN
parse_statement
parse_for_range_statement ::=
T_FOR T_LPAREN parse_init_statement parse_for_range_declaration T_COLON parse_for_range_initializer T_RPAREN
parse_statement
parse_init_statement ::=
parse_simple_declaration parse_maybe_expression
parse_for_range_declaration ::=
parse_decl_specifier_seq ( parse_structured_binding | parse_declarator )
parse_for_range_initializer ::=
parse_expr_or_braced_init_list
parse_if_statement ::=
T_IF (
T_EXCLAIM T_CONSTEVAL parse_compound_statement (T_ELSE parse_statement)?
| T_CONSTEXPR? T_LPAREN parse_init_statement parse_condition T_RPAREN parse_statement (T_ELSE parse_statement)?
)
parse_switch_statement ::=
T_SWITCH T_LPAREN parse_init_statement parse_condition T_RPAREN parse_statement
parse_break_statement ::=
T_BREAK T_SEMICOLON
parse_continue_statement ::=
T_CONTINUE T_SEMICOLON
parse_return_statement ::=
T_RETURN parse_expr_or_braced_init_list? T_SEMICOLON
parse_goto_statement ::=
T_GOTO T_IDENTIFIER T_SEMICOLON
parse_coroutine_return_statement ::=
T_CO_RETURN parse_expr_or_braced_init_list? T_SEMICOLON
parse_try_block ::=
T_TRY parse_compound_statement parse_handler_seq
parse_handler_seq ::=
T_CATCH parse_handler
parse_maybe_compound_statement ::=
parse_compound_statement?
parse_labeled_statement ::=
T_IDENTIFIER T_COLON
parse_declaration_statement ::=
parse_block_declaration
parse_expression_statement ::=
T_SEMICOLON
| parse_maybe_expression T_SEMICOLON
parse_final ::=
parse_id
parse_optional_attribute_specifier_seq ::=
parse_attribute_specifier*
parse_attribute_specifier ::=
parse_cxx_attribute_specifier
| parse_gcc_attribute
| parse_alignment_specifier
| parse_asm_specifier
parse_cxx_attribute_specifier ::=
T_LBRACKET T_LBRACKET parse_attribute_using_prefix parse_attribute_list T_RBRACKET T_RBRACKET
parse_gcc_attribute ::=
T___ATTRIBUTE__ T_LPAREN parse_skip_balanced T_RPAREN
parse_alignment_specifier ::=
T_ALIGNAS T_LPAREN parse_type_id T_DOT_DOT_DOT T_RPAREN
parse_asm_specifier ::=
T_ASM T_LPAREN T_STRING_LITERAL T_RPAREN
//
//Tokens
//
T_SEMICOLON ::= ';'
T_EXTERN ::= "extern"
T_TEMPLATE ::= "template"
T_LESS ::= '<'
T_GREATER ::= '>'
T_LBRACE ::= '{'
T_RBRACE ::= '}'
T_LPAREN ::= '('
T_RPAREN ::= ')'
T_LBRACKET ::= '['
T_RBRACKET ::= ']'
T_COLON ::= ':'
T_COMMA ::= ','
T_EQUAL ::= '='
T_EXCLAIM ::= '!'
T_COLON_COLON ::= "::"
T_NAMESPACE ::= "namespace"
T_INLINE ::= "inline"
T_EXPORT ::= "export"
T_ASM ::= "asm"
T_VOLATILE ::= "volatile"
T_GOTO ::= "goto"
T_STATIC_ASSERT ::= "static_assert"
T_USING ::= "using"
T___EXTENSION__ ::= "__extension__"
T_PRIVATE ::= "private"
T___ATTRIBUTE__ ::= "__attribute__"
T_ALIGNAS ::= "allignas"
T_DOT_DOT_DOT ::= "..."
T_VIRTUAL ::= "virtual"
T_CASE ::= "case"
T_DEFAULT ::= "default"
T_WHILE ::= "while"
T_IF ::= "if"
T_ELSE ::= "else"
T_CONSTEVAL ::= "consteval"
T_SWITCH ::= "switch"
T_BREAK ::= "break"
T_RETURN ::= "return"
T_CO_RETURN ::= "co_return"
T_TRY ::= "try"
T_CATCH ::= "catch"
T_FOR ::= "for"
T_CLASS ::= "class"
T_STRUCT ::= "struct"
T_UNION ::= "union"
T_DELETE ::= "delete"
T_DO ::= "do"
T_CONSTEXPR ::= "constexpr"
T_CONTINUE ::= "continue"
T_STRING_LITERAL ::= '"' ('\' . | [^"\\n\\r\\])* '"'
T_IDENTIFIER ::= [A-Za-z_][A-Za-z0-9_]*
I figured out that the content on specs/grammar.txt come from https://github.com/cplusplus/draft so I made a script to scrap/convert it to an EBNF understood by https://www.bottlecaps.de/rr/ui see the result here https://github.com/cplusplus/draft/issues/6742 .
Thanks for your suggestion but I'm not sure it is a good idea to diverge too much from the official C++ grammar, the C++ language is still evolving. In the past I had a C++ grammar in BNF for pgen, a simple generalized parser generator that I wrote, but it was way too much work to maintain.
https://github.com/robertoraggi/pgen https://github.com/robertoraggi/cplusplus/blob/554e41b4c07b88f7cf51787e37d6b21dcf7481ef/src/cxx/parser.pgen
Not at all ! This one is mechanically extracted from the files at https://github.com/cplusplus/draft/
I've just added the C++11, C++14, C++117, C++20, C++23-draft converted to the EBNF understood by https://www.bottlecaps.de/rr/ui and the navigable railroad diagrams read to view here https://mingodad.github.io/cpp-grammars/ .
Maybe you'll also be interested in https://github.com/thradams/cake and it's playground http://thradams.com/cake/playground.html it has an interesting borrow checker extension.
@mingodad Thanks for the suggestion, it looks like an interesting project to follow. Once I’m done with core language, I plan to implement a few extensions for C++, with reflection and memory safety being on top of my list.
Today I found this project https://github.com/srcML/srcML and they have a wasm playground here http://www.srcml.org/doc/playground.html that is very interesting and I think that it can be interesting to you too.