[back]
# grammar for c++ object declaration, with following simplifications:
#
# only direct and assignment initializer (no brace enclosed initializer)
# no template names
# no abstract parameter declarations
# no throw specifications on function types
# expression is zero, NUMBER or a name
#
# examples:
#
# int i;
# int (* j) (int const * u), k;
# A a, * b, ** c, X::* x;
# int j = 0;
# A::B b (a, b, c, 0);
# int (* q) (int i = 0, ...);
# int (* R::r) (int i = 0 ...) const volatile;
# int (* s) (int f (int i)), (* t) (A (a));
#
# Names can be qualified or unqualified.
#
# This grammar does not permit function declarations:
#
# int f (int u);
#
# This grammar has two fixed ambiguities:
#
# 1. Double colon in nested name.
#
# A ::B
#
# The :: preceding B is treated always as part of the nested name
# A::B, never part of a qualified declarator B
#
# 2. Left parenthesis starting function parameters vs. start of direct
# initializer.
#
# int (* f) (
#
# The left parenthesis is first tried as the start of function
# parameter clause, then tried as the start of direct
# initializer.
#
# On UserTypeNode,
#
# user-type -> name
#
# a real C++ parser would have to check if 'name' is a declared type name.
#
# start rule
start -> simple-decl-seq-opt
# simple declaration seq opt
[]
simple-decl-seq-opt -> simple-decl-seq
simple-decl-seq-opt ->
# simple declaration seq
[]
simple-decl-seq -> simple-decl
[(SeqNode)]
simple-decl-seq -> simple-decl-seq simple-decl
#
# names are used as type names and declarator names
#
# nested name opt
nested-name-opt -> nested-name
nested-name-opt ->
# nested name
#
# a name followed a :: always creates a nested name, the :: is never
# the start of a file scope qualified declarator name
#
[NestedName1Node]
nested-name -> DCOLON
[NestedName2Node]
nested-name -> name DCOLON >!
# name
[NameNode]
name -> nested-name-opt IDENT
#
# declaration specifiers
#
# built-in type
[BltnTypeNode]
bltn-type -> bltn-type-token
# built-in type tokens
bltn-type-token -> BOOL
bltn-type-token -> CHAR
bltn-type-token -> DOUBLE
bltn-type-token -> FLOAT
bltn-type-token -> INT
bltn-type-token -> LONG
bltn-type-token -> SHORT
bltn-type-token -> SIGNED
bltn-type-token -> UNSIGNED
bltn-type-token -> VOID
bltn-type-token -> WCHAR
# user type
[UserTypeNode]
user-type -> name
# cv specifier
[CvSpecNode]
cv-spec -> cv-spec-token
# cv specifier token
cv-spec-token -> CONST
cv-spec-token -> VOLATILE
# cv specifier sequence opt
[]
cv-spec-seq-opt -> cv-spec-seq
cv-spec-seq-opt ->
# cv specifier sequence
[]
cv-spec-seq -> cv-spec
[(SeqNode)]
cv-spec-seq -> cv-spec-seq cv-spec
# ftor (function and storage) specifiers
[FtorSpecNode]
ftor-spec -> ftor-spec-token
# ftor specifier tokens
ftor-spec-token -> INLINE
ftor-spec-token -> VIRTUAL
ftor-spec-token -> EXPLICIT
ftor-spec-token -> STATIC
ftor-spec-token -> EXTERN
ftor-spec-token -> MUTABLE
ftor-spec-token -> AUTO
ftor-spec-token -> REGISTER
#
# declaration specifier sequence
#
# Below we list all possible declaration specifier sequences. We'll
# use the following naming scheme
#
# NAME SEQUENCE OF
# xxVx-decl-spec-seq cv specifiers
# xxxS-decl-spec-seq ftor (function and storage) specifiers
# xBxx-decl-spec-seq built-in type specifiers
# xUxx-decl-spec-seq (one) user type
# Txxx-decl-spec-seq (one) typedef
#
# We combine the names above to form "compound" declaration specifier
# sequences
#
# NAME SEQUENCE OF
# xxVS-decl-spec-seq cv and ftor specifiers
# xBVx-decl-spec-seq built-in type and cv specifiers
# xUVS-decl-spec-seq (one) user type, cv and ftor specifiers
#
# etc.
#
# We could extend this to include
#
# NAME SEQUENCE OF
# Fxxx-decl-spec-seq (one) friend
# xCxx-decl-spec-seq (one) class definition
# xExx-decl-spec-seq (one) elaborated type
# xNxx-decl-spec-seq (one) enum definition
#
# cv
[SeqNode]
xxVx-decl-spec-seq -> xxVx-decl-spec-seq cv-spec
[]
xxVx-decl-spec-seq -> cv-spec
# ftor (function and storage)
[(SeqNode)]
xxxS-decl-spec-seq -> xxxS-decl-spec-seq ftor-spec
[]
xxxS-decl-spec-seq -> ftor-spec
# cv and ftor
[(SeqNode)]
xxVS-decl-spec-seq -> xxVx-decl-spec-seq ftor-spec
[(SeqNode)]
xxVS-decl-spec-seq -> xxxS-decl-spec-seq cv-spec
[(SeqNode)]
xxVS-decl-spec-seq -> xxVS-decl-spec-seq ftor-spec
[(SeqNode)]
xxVS-decl-spec-seq -> xxVS-decl-spec-seq cv-spec
# built-in type
[(SeqNode)]
xBxx-decl-spec-seq -> xBxx-decl-spec-seq bltn-type
[]
xBxx-decl-spec-seq -> bltn-type
# built-in type and cv
[(SeqNode)]
xBVx-decl-spec-seq -> xBxx-decl-spec-seq cv-spec
[(SeqNode)]
xBVx-decl-spec-seq -> xxVx-decl-spec-seq bltn-type
[(SeqNode)]
xBVx-decl-spec-seq -> xBVx-decl-spec-seq cv-spec
[(SeqNode)]
xBVx-decl-spec-seq -> xBVx-decl-spec-seq bltn-type
# built-in type and ftor
[(SeqNode)]
xBxS-decl-spec-seq -> xBxx-decl-spec-seq ftor-spec
[(SeqNode)]
xBxS-decl-spec-seq -> xxxS-decl-spec-seq bltn-type
[(SeqNode)]
xBxS-decl-spec-seq -> xBxS-decl-spec-seq ftor-spec
[(SeqNode)]
xBxS-decl-spec-seq -> xBxS-decl-spec-seq bltn-type
# built-in type, cv and ftor
[(SeqNode)]
xBVS-decl-spec-seq -> xBVx-decl-spec-seq ftor-spec
[(SeqNode)]
xBVS-decl-spec-seq -> xBxS-decl-spec-seq cv-spec
[(SeqNode)]
xBVS-decl-spec-seq -> xxVS-decl-spec-seq bltn-type
[(SeqNode)]
xBVS-decl-spec-seq -> xBVS-decl-spec-seq ftor-spec
[(SeqNode)]
xBVS-decl-spec-seq -> xBVS-decl-spec-seq cv-spec
[(SeqNode)]
xBVS-decl-spec-seq -> xBVS-decl-spec-seq bltn-type
# user type
[ ]
xUxx-decl-spec-seq -> user-type
# user type and cv
[(SeqNode)]
xUVx-decl-spec-seq -> xUxx-decl-spec-seq cv-spec
[(SeqNode)]
xUVx-decl-spec-seq -> xxVx-decl-spec-seq user-type
[(SeqNode)]
xUVx-decl-spec-seq -> xUVx-decl-spec-seq cv-spec
# user type and ftor
[(SeqNode)]
xUxS-decl-spec-seq -> xUxx-decl-spec-seq ftor-spec
[(SeqNode)]
xUxS-decl-spec-seq -> xxxS-decl-spec-seq user-type
[(SeqNode)]
xUxS-decl-spec-seq -> xUxS-decl-spec-seq ftor-spec
# user type, cv and ftor
[(SeqNode)]
xUVS-decl-spec-seq -> xUVx-decl-spec-seq ftor-spec
[(SeqNode)]
xUVS-decl-spec-seq -> xUxS-decl-spec-seq cv-spec
[(SeqNode)]
xUVS-decl-spec-seq -> xxVS-decl-spec-seq user-type
[(SeqNode)]
xUVS-decl-spec-seq -> xUVS-decl-spec-seq ftor-spec
[(SeqNode)]
xUVS-decl-spec-seq -> xUVS-decl-spec-seq cv-spec
# typedef
[ ]
Txxx-decl-spec-seq -> TYPEDEF
# typedef and cv
[(SeqNode)]
TxVx-decl-spec-seq -> Txxx-decl-spec-seq cv-spec
[(SeqNode)]
TxVx-decl-spec-seq -> xxVx-decl-spec-seq TYPEDEF
[(SeqNode)]
TxVx-decl-spec-seq -> TxVx-decl-spec-seq cv-spec
# typedef and ftor
[(SeqNode)]
TxxS-decl-spec-seq -> Txxx-decl-spec-seq ftor-spec
[(SeqNode)]
TxxS-decl-spec-seq -> xxxS-decl-spec-seq TYPEDEF
[(SeqNode)]
TxxS-decl-spec-seq -> TxxS-decl-spec-seq ftor-spec
# typedef, cv and ftor
[(SeqNode)]
TxVS-decl-spec-seq -> TxVx-decl-spec-seq ftor-spec
[(SeqNode)]
TxVS-decl-spec-seq -> TxxS-decl-spec-seq cv-spec
[(SeqNode)]
TxVS-decl-spec-seq -> xxVS-decl-spec-seq TYPEDEF
[(SeqNode)]
TxVS-decl-spec-seq -> TxVS-decl-spec-seq ftor-spec
[(SeqNode)]
TxVS-decl-spec-seq -> TxVS-decl-spec-seq cv-spec
# typedef and built-in type
[(SeqNode)]
TBxx-decl-spec-seq -> Txxx-decl-spec-seq bltn-type
[(SeqNode)]
TBxx-decl-spec-seq -> xBxx-decl-spec-seq TYPEDEF
[(SeqNode)]
TBxx-decl-spec-seq -> TBxx-decl-spec-seq bltn-type
# typedef, built-in type and cv
[(SeqNode)]
TBVx-decl-spec-seq -> TBxx-decl-spec-seq cv-spec
[(SeqNode)]
TBVx-decl-spec-seq -> TxVx-decl-spec-seq bltn-type
[(SeqNode)]
TBVx-decl-spec-seq -> xBVx-decl-spec-seq TYPEDEF
[(SeqNode)]
TBVx-decl-spec-seq -> TBVx-decl-spec-seq cv-spec
[(SeqNode)]
TBVx-decl-spec-seq -> TBVx-decl-spec-seq bltn-type
# typedef, built-in type and ftor
[(SeqNode)]
TBxS-decl-spec-seq -> TBxx-decl-spec-seq ftor-spec
[(SeqNode)]
TBxS-decl-spec-seq -> TxxS-decl-spec-seq bltn-type
[(SeqNode)]
TBxS-decl-spec-seq -> xBxS-decl-spec-seq TYPEDEF
[(SeqNode)]
TBxS-decl-spec-seq -> TBxS-decl-spec-seq ftor-spec
[(SeqNode)]
TBxS-decl-spec-seq -> TBxS-decl-spec-seq bltn-type
# typedef, built-in type, cv and ftor
[(SeqNode)]
TBVS-decl-spec-seq -> TBVx-decl-spec-seq ftor-spec
[(SeqNode)]
TBVS-decl-spec-seq -> TBxS-decl-spec-seq cv-spec
[(SeqNode)]
TBVS-decl-spec-seq -> TxVS-decl-spec-seq bltn-type
[(SeqNode)]
TBVS-decl-spec-seq -> xBVS-decl-spec-seq TYPEDEF
[(SeqNode)]
TBVS-decl-spec-seq -> TBVS-decl-spec-seq ftor-spec
[(SeqNode)]
TBVS-decl-spec-seq -> TBVS-decl-spec-seq cv-spec
[(SeqNode)]
TBVS-decl-spec-seq -> TBVS-decl-spec-seq bltn-type
# typedef and user type
[(SeqNode)]
TUxx-decl-spec-seq -> Txxx-decl-spec-seq user-type
[(SeqNode)]
TUxx-decl-spec-seq -> xUxx-decl-spec-seq TYPEDEF
# typedef, user type and cv
[(SeqNode)]
TUVx-decl-spec-seq -> TUxx-decl-spec-seq cv-spec
[(SeqNode)]
TUVx-decl-spec-seq -> TxVx-decl-spec-seq user-type
[(SeqNode)]
TUVx-decl-spec-seq -> xUVx-decl-spec-seq TYPEDEF
[(SeqNode)]
TUVx-decl-spec-seq -> TUVx-decl-spec-seq cv-spec
# typedef, user type and ftor
[(SeqNode)]
TUxS-decl-spec-seq -> TUxx-decl-spec-seq ftor-spec
[(SeqNode)]
TUxS-decl-spec-seq -> TxxS-decl-spec-seq user-type
[(SeqNode)]
TUxS-decl-spec-seq -> xUxS-decl-spec-seq TYPEDEF
[(SeqNode)]
TUxS-decl-spec-seq -> TUxS-decl-spec-seq ftor-spec
# typedef, user type, cv and ftor
[(SeqNode)]
TUVS-decl-spec-seq -> TUVx-decl-spec-seq ftor-spec
[(SeqNode)]
TUVS-decl-spec-seq -> TUxS-decl-spec-seq cv-spec
[(SeqNode)]
TUVS-decl-spec-seq -> TxVS-decl-spec-seq user-type
[(SeqNode)]
TUVS-decl-spec-seq -> xUVS-decl-spec-seq TYPEDEF
[(SeqNode)]
TUVS-decl-spec-seq -> TUVS-decl-spec-seq ftor-spec
[(SeqNode)]
TUVS-decl-spec-seq -> TUVS-decl-spec-seq cv-spec
#
# simple declaration
#
# simple declaration
[SimpleDeclNode]
simple-decl -> nested-decl SEMI
# nested declaration
[]
nested-decl * -> nested-obj-init-decl
# object declaration with initializer
[ObjInitDeclNode]
nested-obj-init-decl -> nested-obj-decl obj-init-opt
# object inititalizer opt
obj-init-opt -> obj-init
obj-init-opt ->
# object initializer
[ObjInit1Node]
obj-init -> ASSIGN expr
[ObjInit2Node]
obj-init -> LPAREN expr-list RPAREN
# expr list
[]
expr-list -> expr
[(SeqNode)]
expr-list -> expr-list COMMA expr
# nested object declarator
#
# try obj-dcl before initializer, example:
#
# int (* i) (
#
# try left paren as start of function parameters before direct initializer
#
[NestedObjDecl1Node]
nested-obj-decl -> nested-decl COMMA obj-dcl >
[NestedObjDecl2Node]
nested-obj-decl -> obj-decl >
# object decl
[ Decl1Node ]
obj-decl -> xBxx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xBVx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xBxS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xBVS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xUxx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xUVx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xUxS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> xUVS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TBxx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TBVx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TBxS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TBVS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TUxx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TUVx-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TUxS-decl-spec-seq obj-dcl
[(Decl1Node)]
obj-decl -> TUVS-decl-spec-seq obj-dcl
#
# object declarator
#
[]
obj-dcl -> obj-a-dcl
# object-a declarator
[DclNode]
obj-a-dcl -> ptr-oper obj-a-dcl
[]
obj-a-dcl -> obj-a-direct-dcl
# object-b declarator
[(DclNode)]
obj-b-dcl -> ptr-oper obj-a-dcl
[]
obj-b-dcl -> obj-b-direct-dcl
# object-a direct declarator
[]
obj-a-direct-dcl -> obj-b-direct-dcl
[]
obj-a-direct-dcl -> obj-dcl-id
# object-a direct declarator
[DirectDcl1Node]
obj-b-direct-dcl -> obj-b-direct-dcl LPAREN param-decl-clause RPAREN cv-spec-seq-opt
[DirectDcl2Node]
obj-b-direct-dcl -> obj-a-direct-dcl LBRACK expr RBRACK
[DirectDcl3Node]
obj-b-direct-dcl -> LPAREN obj-b-dcl RPAREN
# object declarator id
obj-dcl-id -> obj-id
[(DirectDcl3Node)]
obj-dcl-id -> LPAREN obj-dcl-id RPAREN
# object id
[IdNode]
obj-id -> name
# pointer operator
[PtrOper1Node]
ptr-oper -> TIMES cv-spec-seq-opt
[PtrOper2Node]
ptr-oper -> AMPERSAND
[PtrOper3Node]
ptr-oper -> name DCOLON TIMES cv-spec-seq-opt
#
# parameter declaration
#
# parameter declaration clause
[ParamDeclClause1Node]
param-decl-clause -> param-decl-list-opt ellipse-opt
[ParamDeclClause2Node]
param-decl-clause -> param-decl-list COMMA ELLIPSE
# ellipse opt
ellipse-opt -> ELLIPSE
ellipse-opt ->
# parameter declaration list opt
[]
param-decl-list-opt -> param-decl-list
param-decl-list-opt ->
# parameter declaration list
[]
param-decl-list -> param-init-decl
[(SeqNode)]
param-decl-list -> param-decl-list COMMA param-init-decl
# parameter declaration with initializer (default argument)
[ParamInitDecl1Node]
param-init-decl -> param-decl
[ParamInitDecl2Node]
param-init-decl -> param-decl ASSIGN expr
# parameter declaration
[(Decl1Node)]
param-decl -> xBxx-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xBVx-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xBxS-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xBVS-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xUxx-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xUVx-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xUxS-decl-spec-seq param-dcl
[(Decl1Node)]
param-decl -> xUVS-decl-spec-seq param-dcl
# parameter declarator
# similar to object declarator except permits (implicit pointer to function) declarations
# of the form
# int f (int i)
[]
param-dcl -> param-a-dcl
# param a dcl
[(DclNode)]
param-a-dcl -> ptr-oper param-a-dcl
[]
param-a-dcl -> param-a-direct-dcl
# param b dcl
[(DclNode)]
param-b-dcl -> ptr-oper param-a-dcl
[]
param-b-dcl -> param-b-direct-dcl
# param a direct dcl
[]
param-a-direct-dcl -> param-b-direct-dcl
[]
param-a-direct-dcl -> obj-dcl-id
# param b direct dcl
[(DirectDcl1Node)]
param-b-direct-dcl -> param-a-direct-dcl LPAREN param-decl-clause RPAREN cv-spec-seq-opt
[(DirectDcl2Node)]
param-b-direct-dcl -> param-a-direct-dcl LBRACK expr RBRACK
[(DirectDcl3Node)]
param-b-direct-dcl -> LPAREN param-b-dcl RPAREN
#
# expression
#
# expression can be a name or a number
#
[Expr1Node]
expr -> name
[Expr2Node]
expr -> NUMBER
[Expr3Node]
expr -> ZERO
[back]