[back]
# Grammar for tempate-id with type and non-type template arguments
#
# This grammar has several resolved conflicts:
#
# 1) A <1 > 2>
#
# The first non-nested '>' terminates a template id, so '1 > 2' is
# never a template non-type argument.
#
# This is fixed by giving the GT a first priority with an exclusive
# modifier:
#
# name -> nested-name-opt IDENT LT template-arg-list-opt GT ^!
#
# The same could have been achieved by giving template-arg-list-opt
# a reduce priority with an exclusive modifier:
#
# name -> nested-name-opt IDENT LT template-arg-list-opt +! GT
#
# 2) A <1, 2>
#
# The ',' is never the comma in a comma-expr.
#
# This is fixed by giving COMMA a first priority with an
# exclusive modifier:
#
# template-arg-list -> template-arg-list COMMA ^! template-arg
#
# 3) A <B> or A <B * C>
#
# The 'B' should first be tried as a type name, then as an expression.
#
# This is fixed by giving the abstract declaration one shift priority
# and one reduce priority:
#
# template-arg -> abstract-decl >+
# template-arg -> expr
#
# The shift priority is for cases like 'B * C', the reduce priority
# is for cases like 'B'.
#
# 4) A <int (*) (int)>
#
# The first '(' is tried as the start of a nested abstract declarator,
# then as the start of a parameter list.
#
# This is fixed by giving LPAREN a shift priority:
#
# abstract-direct-dcl -> LPAREN > abstract-dcl RPAREN
#
# 5) A <(B <C>)>
#
# B is first tried as a template name, then as an expression. A real
# C++ compiler would check on the template name reduction if 'B' is
# a declared template.
#
# This is fixed by giving name one shift prioirty:
#
# primary-expr -> name >
#
# Note that in 'A <B <C> >' the conflict doesn't arise because we've
# already given abstract-decl a shift priority (see 3 above).
#
# The best way to understand the conflicts is to remove the fix then run basil
# and look at the log file.
#
# start rule
start -> name
# name
[Name1Node]
name -> nested-name-opt IDENT
[Name2Node]
name -> nested-name-opt IDENT LT template-arg-list-opt GT ^!
# nested name opt
nested-name-opt -> nested-name
nested-name-opt ->
# nested name
[NestedName1Node]
nested-name -> DCOLON
[NestedName2Node]
nested-name -> name DCOLON >!
#
# template argument list
#
# template arg list opt
template-arg-list-opt -> template-arg-list
template-arg-list-opt ->
# template arg list
template-arg-list -> template-arg
template-arg-list -> template-arg-list COMMA ^! template-arg
# template arg
template-arg -> abstract-decl >+
template-arg -> expr
#
# abstract decl
#
[ AbstractDeclNode ]
abstract-decl -> xBxx-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xBVx-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xBxS-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xBVS-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xUxx-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xUVx-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xUxS-decl-spec-seq abstract-dcl-opt
[(AbstractDeclNode)]
abstract-decl -> xUVS-decl-spec-seq abstract-dcl-opt
#
# abstract declarator: declarator without an id
#
# abstract declarator
[AbstractDclNode]
abstract-dcl -> ptr-oper abstract-dcl-opt
[]
abstract-dcl -> abstract-direct-dcl
# abstract direct declarator
[AbstractDirectDcl1Node]
abstract-direct-dcl -> abstract-direct-dcl-opt LPAREN param-decl-clause RPAREN cv-spec-seq-opt
[AbstractDirectDcl2Node]
abstract-direct-dcl -> abstract-direct-dcl-opt LBRACK expr-opt RBRACK
# try a nested abstract declarator before an empty abstract direct declarator
[AbstractDirectDcl3Node]
abstract-direct-dcl -> LPAREN > abstract-dcl RPAREN
# abstract declarator opt
[]
abstract-dcl-opt -> abstract-dcl
abstract-dcl-opt ->
# abstract direct declarator opt
[]
abstract-direct-dcl-opt -> abstract-direct-dcl
abstract-direct-dcl-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-decl
[(SeqNode)]
param-decl-list -> param-decl-list COMMA param-decl
# parameter declaration
[ ParamDeclNode ]
param-decl -> xBxx-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xBVx-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xBxS-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xBVS-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xUxx-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xUVx-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xUxS-decl-spec-seq param-dcl
[(ParamDeclNode)]
param-decl -> xUVS-decl-spec-seq param-dcl
#
# parameter declarator
#
[]
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
#
# 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
#
# 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
#
# expression
#
# expr opt
expr-opt -> expr
expr-opt ->
# expr
[ExprNode]
expr -> comma-expr
# comma expr
[CommaExprNode]
comma-expr -> comma-expr COMMA assign-expr
[]
comma-expr -> assign-expr
# assign expr
[G_AssignExprNode ]
assign-expr -> log-or-expr ASSIGN assign-expr
[]
assign-expr -> cond-expr
# conditional expr
[CondExprNode]
cond-expr -> log-or-expr QMARK expr COLON assign-expr
[]
cond-expr -> log-or-expr
# logical or expression
[LogOrExprNode]
log-or-expr -> log-or-expr OR log-and-expr
[]
log-or-expr -> log-and-expr
# logical and expression
[LogAndExprNode]
log-and-expr -> log-and-expr AND incl-or-expr
[]
log-and-expr -> incl-or-expr
# inclusive or expression
[InclOrExprNode]
incl-or-expr -> incl-or-expr BITOR excl-or-expr
[]
incl-or-expr -> excl-or-expr
# exclusive or expression
[ExclOrExprNode]
excl-or-expr -> excl-or-expr XOR and-expr
[]
excl-or-expr -> and-expr
# and expression
[AndExprNode]
and-expr -> and-expr BITAND eq-expr
[]
and-expr -> eq-expr
# equality expression
[G_EqExpr1Node ]
eq-expr -> eq-expr EQ rel-expr
[G_EqExpr2Node ]
eq-expr -> eq-expr NOTEQ rel-expr
[]
eq-expr -> rel-expr
# rel expression
[RelExpr1Node]
rel-expr -> rel-expr LT shift-expr
[RelExpr2Node]
rel-expr -> rel-expr GT shift-expr
[RelExpr3Node]
rel-expr -> rel-expr LTEQ shift-expr
[RelExpr4Node]
rel-expr -> rel-expr GTEQ shift-expr
[]
rel-expr -> shift-expr
# shift expression
[ShiftExpr1Node]
shift-expr -> shift-expr LSHIFT add-expr
[ShiftExpr2Node]
shift-expr -> shift-expr RSHIFT add-expr
[]
shift-expr -> add-expr
# additive expression
[AddExpr1Node]
add-expr -> add-expr PLUS mult-expr
[AddExpr2Node]
add-expr -> add-expr MINUS mult-expr
[]
add-expr -> mult-expr
# multipicative expression
#
# assume primary expr is next (skip cast, unary, postfix)
#
[MultExpr1Node]
mult-expr -> mult-expr TIMES primary-expr
[MultExpr2Node]
mult-expr -> mult-expr DIVIDE primary-expr
[MultExpr3Node]
mult-expr -> mult-expr MOD primary-expr
[]
mult-expr -> primary-expr
# primary expr
# assume a primary expr is a number, name or a nested expression
[PrimaryExpr1Node]
primary-expr -> NUMBER
[PrimaryExpr2Node]
primary-expr -> name >
[PrimaryExpr3Node]
primary-expr -> LPAREN expr RPAREN
[back]