fixed problems with declaration syntax

This commit is contained in:
eck 1990-09-03 13:46:30 +00:00
parent 2f83a7e3d9
commit 02ea4988d1
3 changed files with 56 additions and 64 deletions

View file

@ -67,43 +67,38 @@ declaration
short typedef yepp;
makes all hope of writing a specific grammar for typedefs illusory.
*/
/* We do not accept the whole of the grammar, since when we see
something like 'unsigned plain' (where plain is a typedef) is
illegal if 'plain' is a typedef. Therefore, we assume that
'plain' is the identifier of a declarator. Unfortunately, this
causes declarations like 'unsigned plain x;' to be rejected on the
grounds of syntax, even though it is syntactically right. This may
cause a lot of extra messages.
To do this, decl_specifiers is divided into:
1: normal specifiers == storage class specifiers + type_qualifiers
2: special specifiers == short + long + signed + unsigned
3: basic types == void + char + int + float + double
4: single type specifiers == struct or union specifiers
+ enum specifiers + typedef names
/* Accept a single declaration specifier. Then accept zero or more
type-specifiers. There can be a conflict on both TYPE_IDENTIFIER
and IDENTIFIER.
The following rule is used:
When we see a TYPE_IDENTIFIER, we accept it if no type-specifier
was given, and it is not directly followed by an identifier.
If no type-dpecifier was given, it is taken as the identifier being
declared. If it is followed by an identifier, we assume that an
error has been made, (e.g. unsigned typedeffed_int x;) and that
this will be detected later on.
When we see an IDENTIFIER, directly followed by another IDENTIFIER,
we assume that a typing mistake has been made, and we accept it as
an erroneous type-identifier.
*/
*/
decl_specifiers /* non-empty */ (register struct decspecs *ds;)
/* Reads a non-empty decl_specifiers and fills the struct
decspecs *ds.
*/
:
[ %if (AHEAD == IDENTIFIER) /* like: register i; */
normal_specifier(ds)
|
normal_specifier(ds)*
[ special_specifier(ds)
| basic_type(ds)
| single_type_specifier(ds)
]
[ normal_specifier(ds)
| special_specifier(ds)
| basic_type(ds)
single_decl_specifier(ds)
[ %while( (DOT==TYPE_IDENTIFIER
&& ds->ds_size == 0
&& ds->ds_unsigned == 0
&& ds->ds_type == (struct type *)0)
|| AHEAD == IDENTIFIER) /* always an error */
single_decl_specifier(ds)
]*
]
{do_decspecs(ds);}
;
normal_specifier(register struct decspecs *ds;)
single_decl_specifier /* non_empty */ (register struct decspecs *ds;)
:
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
{ if (ds->ds_sc_given)
@ -112,28 +107,18 @@ normal_specifier(register struct decspecs *ds;)
ds->ds_sc = DOT;
}
|
/* This qualifier applies to the top type.
E.g. volatile float * is a pointer to volatile float.
*/
VOLATILE
{ if (ds->ds_typequal & TQ_VOLATILE)
error("repeated type qualifier");
ds->ds_typequal |= TQ_VOLATILE;
}
|
/* This qualifier applies to the top type.
E.g. volatile float * is a pointer to volatile float.
*/
CONST
{
if (ds->ds_typequal & TQ_CONST)
{ if (ds->ds_typequal & TQ_CONST)
error("repeated type qualifier");
ds->ds_typequal |= TQ_CONST;
}
;
special_specifier(register struct decspecs *ds;)
:
|
[ SHORT | LONG ]
{ if (ds->ds_size)
error("repeated size specifier");
@ -145,35 +130,14 @@ special_specifier(register struct decspecs *ds;)
error("repeated sign specifier");
ds->ds_unsigned = DOT;
}
;
/* 3.5.2 */
type_specifier(struct type **tpp;)
/* Used in struct/union declarations and in casts; only the
type is relevant.
*/
{struct decspecs Ds; Ds = null_decspecs;}
:
decl_specifiers(&Ds)
{
if (Ds.ds_sc_given)
error("storage class ignored");
if (Ds.ds_sc == REGISTER)
error("register ignored");
}
{*tpp = Ds.ds_type;}
;
basic_type(register struct decspecs *ds;):
|
[ VOID | CHAR | INT | FLOAT | DOUBLE ]
{
idf2type(dot.tk_idf, &ds->ds_type);
ds->ds_typedef = 0;
}
;
single_type_specifier(register struct decspecs *ds;):
%default TYPE_IDENTIFIER /* this includes INT, CHAR, etc. */
|
%default TYPE_IDENTIFIER
{
idf2type(dot.tk_idf, &ds->ds_type);
ds->ds_typedef = 1;
@ -194,6 +158,23 @@ single_type_specifier(register struct decspecs *ds;):
enum_specifier(&ds->ds_type)
;
/* 3.5.2 */
type_specifier(struct type **tpp;)
/* Used in struct/union declarations and in casts; only the
type is relevant.
*/
{struct decspecs Ds; Ds = null_decspecs;}
:
decl_specifiers(&Ds)
{
if (Ds.ds_sc_given)
error("storage class ignored");
if (Ds.ds_sc == REGISTER)
error("register ignored");
}
{*tpp = Ds.ds_type;}
;
/* 3.5 */
init_declarator_list(struct decspecs *ds;):
init_declarator(ds)

View file

@ -195,6 +195,17 @@ int to_endif;
*/
switch(tk.tk_idf->id_resmac) {
default:
case K_UNKNOWN:
/* invalid word seen after the '#' */
lexerror("%s: unknown control", tk.tk_idf->id_text);
/* fallthrough */
case K_DEFINE:
case K_ERROR:
case K_INCLUDE:
case K_LINE:
case K_PRAGMA:
case K_UNDEF:
case K_FILE:
SkipToNewLine();
break;
case K_IF:

View file

@ -41,8 +41,8 @@ enter_label(idf, defining)
}
else {
add_def(idf, LABEL, label_type, L_LOCAL);
def = idf->id_def;
}
def = idf->id_def; /* might be changed by 1 of the 2 add_defs */
if (def->df_address == 0)
def->df_address = (arith) text_label();
if (defining)