Next: Declarators
Up: Syntactic structure
Previous: Expressions
A declaration specifies the interpretation and attributes of a set of
identifiers.
The declaration_specifiers phrase consists of a sequence of specifiers
that indicate the linkage, storage duration, and part of the type of the
entities denoted in the init_declarator_list_opt.
This macro is defined in definitions 3, 7, 8, 9, 10, 11, 12, 13, 14, 1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, and 27.
This macro is invoked in definition 6.
Specifiers appearing in the declaration_specifiers phrase must be
drawn from one of the three sets (storage class specifiers, type specifiers,
type qualifiers) defined in Section 6.5 of the standard.
Five of the type specifiers can only appear in lists of one element;
the other seven can be used to form lists of one or more elements.
It is important to distinguish the two kinds of type specifiers
syntactically in order to parse a sequence like ``int j;''
properly when j has been declared in an outer scope to be a
typedef_name:
If the parser knows that a typedef_name cannot follow the
type_specifier int, then it will be forced to re-classify j as
an identifier.
If this information is not available to the parser, then it will detect a
syntax error after accepting j as a type_specifier and not finding
an identifier.
At that point, however, it is too late to re-classify j.
The type_specifiers that must appear singly are therefore
classified as type_specifier_1s, and those that may appear in groups
are classified as type_specifier_2s.
The phrase declaration_specifiers is then defined to enforce the
constraint syntactically.
All lists must be left-recursive here in order to detect the error at the
proper symbol:
declaration_specifiers:
ds0 / ds1 / ds2.
ds0: /* List without type specifiers */
storage_class_specifier / ds0 storage_class_specifier /
type_qualifier / ds0 type_qualifier .
ds1: /* List with a single type_specifier_1 */
type_specifier_1 / ds0 type_specifier_1 /
ds1 storage_class_specifier / ds1 type_qualifier .
ds2: /* List with one or more type_specifier_2's */
type_specifier_2 / ds0 type_specifier_2 /
ds2 type_specifier_2 / ds2 storage_class_specifier / ds2 type_qualifier .
storage_class_specifier:
'typedef' &'Accept a typedef specifier[32]' /
'extern' /
'static' /
'auto' /
'register' .
type_specifier_1:
'void' /
'float' /
struct_or_union_specifier /
enum_specifier /
typedef_name .
type_specifier_2:
'char' /
'short' /
'int' /
'long' /
'double' /
'signed' /
'unsigned' .
struct_or_union_specifier:
struct_or_union identifier
&'Nest[34](`member_def',`0')' '{' struct_declaration_list &'Restore[36]' '}' /
struct_or_union
&'Nest[34](`member_def',`0')' '{' struct_declaration_list &'Restore[36]' '}' /
struct_or_union identifier $';' .
This macro is defined in definitions 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, and 27.
This macro is invoked in definition 6.
The modifier $';' in the last line above prevents a reduction to
struct_or_union_specifier if the lookahead symbol is ;.
A modifier is only effective, however, if there is a conflict.
There is no conflict in this grammar involving that alternative:
struct_or_union identifier may be followed by either a declarator
or a ; and the reduction to a struct_or_union_specifier is valid.
Section 6.5.2.3 of the standard gives the two cases quite different
semantics, however.
If struct_or_union identifier is followed by a ; then the
identifier is a structure or union tag that specifies a new type
distinct from any type with the same tag in an enclosing scope (if any).
Otherwise it will specify a new type only if there is no structure or union
with that tag visible at that point.
When constructing an abstract syntax tree, it is useful to distinguish
these contexts by first reducing the identifier to a separate
nonterminal and then reducing the result.
If this is done, and the given modifier is not present, then a conflict
will be introduced into the grammar.
The modifier is therefore inserted here in order to allow construction of
an appropriate abstract syntax tree without the need to alter this
specification.
struct_or_union:
'struct' /
'union' .
struct_declaration_list: struct_declaration+ .
struct_declaration:
specifier_qualifier_list struct_declarator_list ';'.
This macro is defined in definitions 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, and 27.
This macro is invoked in definition 6.
A specifier_qualifier_list phrase differs from a
declaration_specifiers phrase only in the fact that
storage class specifiers are not allowed.
The same problem with type specifiers must be solved, and the same
mechanism is used.
specifier_qualifier_list:
sq0 / sq1 / sq2 .
sq0: /* List without type specifiers */
type_qualifier / sq0 type_qualifier .
sq1: /* List with a single type_specifier_1 */
type_specifier_1 / sq0 type_specifier_1 / sq1 type_qualifier .
sq2: /* List with one or more type_specifier_2's */
type_specifier_2 / sq0 type_specifier_2 /
sq2 type_specifier_2 / sq2 type_qualifier .
struct_declarator_list: struct_declarator // ',' .
struct_declarator:
member_declarator /
member_declarator ':' constant_expression /
':' constant_expression .
member_declarator:
member_pointer_declarator /
member_direct_declarator .
member_direct_declarator:
MemberIdDef $')' /
'(' member_declarator ')' /
member_array_declarator /
member_function_declarator .
member_pointer_declarator:
'*' type_qualifier_list_opt member_declarator .
member_array_declarator:
member_direct_declarator '[' constant_exp_opt ']' .
member_function_declarator:
member_direct_declarator '(' empty_parameter_type_list ')' /
member_direct_declarator
'(' &'Nest[34](`identifier',`0')' parameter_type_list &'Restore[36]' ')' .
MemberIdDef:
member_def &'Bind[47]' /
'(' MemberIdDef ')' .
enum_specifier:
'enum' identifier
&'Nest[34](`identifier',`1')' '{' enumerator_list &'Restore[36]' '}' /
'enum'
&'Nest[34](`identifier',`1')' '{' enumerator_list &'Restore[36]' '}' /
'enum' identifier .
enumerator_list:
enumerator /
enumerator_list ',' enumerator .
enumerator:
enumeration_constant /
enumeration_constant '=' constant_expression.
enumeration_constant:
identifier &'Bind[47]' .
type_qualifier:
'const' /
'volatile'.
This macro is defined in definitions 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, and 27.
This macro is invoked in definition 6.
Subsections
Next: Declarators
Up: Syntactic structure
Previous: Expressions
2008-08-30