fixed int to unsigned conversions, declarations, pp-list initialization
This commit is contained in:
@@ -67,28 +67,43 @@ 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
|
||||
|
||||
*/
|
||||
decl_specifiers /* non-empty */ (register struct decspecs *ds;)
|
||||
/* Reads a non-empty decl_specifiers and fills the struct
|
||||
decspecs *ds.
|
||||
*/
|
||||
:
|
||||
[
|
||||
other_specifier(ds)+
|
||||
[%if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
|
||||
/* the thin ice in R.M. 11.1 */
|
||||
single_type_specifier(ds) other_specifier(ds)*
|
||||
|
|
||||
empty
|
||||
]
|
||||
[ %if (AHEAD == IDENTIFIER) /* like: register i; */
|
||||
normal_specifier(ds)
|
||||
|
|
||||
single_type_specifier(ds) other_specifier(ds)*
|
||||
normal_specifier(ds)*
|
||||
[ special_specifier(ds)
|
||||
| basic_type(ds)
|
||||
| single_type_specifier(ds)
|
||||
]
|
||||
[ normal_specifier(ds)
|
||||
| special_specifier(ds)
|
||||
| basic_type(ds)
|
||||
]*
|
||||
]
|
||||
{do_decspecs(ds);}
|
||||
;
|
||||
|
||||
/* 3.5.1 & 3.5.2 (partially) & 3.5.3 (partially) */
|
||||
other_specifier(register struct decspecs *ds;)
|
||||
normal_specifier(register struct decspecs *ds;)
|
||||
:
|
||||
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
|
||||
{ if (ds->ds_sc_given)
|
||||
@@ -96,18 +111,6 @@ other_specifier(register struct decspecs *ds;)
|
||||
ds->ds_sc_given = 1;
|
||||
ds->ds_sc = DOT;
|
||||
}
|
||||
|
|
||||
[ SHORT | LONG ]
|
||||
{ if (ds->ds_size)
|
||||
error("repeated size specifier");
|
||||
ds->ds_size = DOT;
|
||||
}
|
||||
|
|
||||
[ SIGNED | UNSIGNED ]
|
||||
{ if (ds->ds_unsigned != 0)
|
||||
error("repeated sign specifier");
|
||||
ds->ds_unsigned = DOT;
|
||||
}
|
||||
|
|
||||
/* This qualifier applies to the top type.
|
||||
E.g. volatile float * is a pointer to volatile float.
|
||||
@@ -129,6 +132,21 @@ other_specifier(register struct decspecs *ds;)
|
||||
}
|
||||
;
|
||||
|
||||
special_specifier(register struct decspecs *ds;)
|
||||
:
|
||||
[ SHORT | LONG ]
|
||||
{ if (ds->ds_size)
|
||||
error("repeated size specifier");
|
||||
ds->ds_size = DOT;
|
||||
}
|
||||
|
|
||||
[ SIGNED | UNSIGNED ]
|
||||
{ if (ds->ds_unsigned != 0)
|
||||
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
|
||||
@@ -146,9 +164,20 @@ type_specifier(struct type **tpp;)
|
||||
{*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. */
|
||||
{idf2type(dot.tk_idf, &ds->ds_type);}
|
||||
{
|
||||
idf2type(dot.tk_idf, &ds->ds_type);
|
||||
ds->ds_typedef = 1;
|
||||
}
|
||||
|
|
||||
IDENTIFIER
|
||||
{
|
||||
@@ -283,7 +312,7 @@ declarator(register struct declarator *dc;)
|
||||
|
|
||||
formal_list(&fm)
|
||||
|
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
')'
|
||||
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
|
||||
@@ -308,6 +337,7 @@ arrayer(arith *sizep;)
|
||||
{ struct expr *expr; }
|
||||
:
|
||||
'['
|
||||
{ *sizep = (arith)-1; }
|
||||
[
|
||||
constant_expression(&expr)
|
||||
{
|
||||
@@ -315,10 +345,7 @@ arrayer(arith *sizep;)
|
||||
*sizep = expr->VL_VALUE;
|
||||
free_expression(expr);
|
||||
}
|
||||
|
|
||||
empty
|
||||
{ *sizep = (arith)-1; }
|
||||
]
|
||||
]?
|
||||
']'
|
||||
;
|
||||
|
||||
@@ -358,7 +385,7 @@ enum_specifier(register struct type **tpp;)
|
||||
enumerator_pack(*tpp, &l)
|
||||
|
|
||||
{apply_struct(ENUM, idf, tpp);}
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
]
|
||||
;
|
||||
@@ -433,7 +460,7 @@ struct_or_union_specifier(register struct type **tpp;)
|
||||
if (DOT == ';') declare_struct(fund, idf, tpp);
|
||||
else apply_struct(fund, idf, tpp);
|
||||
}
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
]
|
||||
;
|
||||
@@ -533,7 +560,7 @@ abstract_declarator(register struct declarator *dc;)
|
||||
[
|
||||
parameter_type_list(&pl)
|
||||
|
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
')'
|
||||
{add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);}
|
||||
@@ -551,7 +578,7 @@ abstract_declarator(register struct declarator *dc;)
|
||||
primary_abstract_declarator(struct declarator *dc;)
|
||||
:
|
||||
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
|
||||
empty
|
||||
/* empty */
|
||||
|
|
||||
'(' abstract_declarator(dc) ')'
|
||||
]
|
||||
@@ -663,7 +690,7 @@ primary_parameter_declarator(register struct declarator *dc;)
|
||||
:
|
||||
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
|
||||
&& (AHEAD != IDENTIFIER))
|
||||
empty
|
||||
/* empty */
|
||||
|
|
||||
identifier(&dc->dc_idf)
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user