495 lines
		
	
	
	
		
			9.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			495 lines
		
	
	
	
		
			9.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/*
 | 
						|
 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
						|
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
						|
 */
 | 
						|
/* $Header$ */
 | 
						|
/*	DECLARATION SYNTAX PARSER	*/
 | 
						|
 | 
						|
{
 | 
						|
#include	<alloc.h>
 | 
						|
#include	"nobitfield.h"
 | 
						|
#include	"debug.h"
 | 
						|
#include	"arith.h"
 | 
						|
#include	"LLlex.h"
 | 
						|
#include	"idf.h"
 | 
						|
#include	"type.h"
 | 
						|
#include	"struct.h"
 | 
						|
#include	"field.h"
 | 
						|
#include	"decspecs.h"
 | 
						|
#include	"def.h"
 | 
						|
#include	"declar.h"
 | 
						|
#include	"label.h"
 | 
						|
#include	"expr.h"
 | 
						|
#include	"sizes.h"
 | 
						|
#include	"level.h"
 | 
						|
 | 
						|
extern char options[];
 | 
						|
}
 | 
						|
 | 
						|
/* 8 */
 | 
						|
declaration
 | 
						|
	{struct decspecs Ds;}
 | 
						|
:
 | 
						|
	{Ds = null_decspecs;}
 | 
						|
	decl_specifiers(&Ds)
 | 
						|
	init_declarator_list(&Ds)?
 | 
						|
	';'
 | 
						|
;
 | 
						|
 | 
						|
/*	A `decl_specifiers' describes a sequence of a storage_class_specifier,
 | 
						|
	an unsigned_specifier, a size_specifier and a simple type_specifier,
 | 
						|
	which may occur in arbitrary order and each of which may be absent;
 | 
						|
	at least one of them must be present, however, since the totally
 | 
						|
	empty case has already be dealt with in `external_definition'.
 | 
						|
	This means that something like:
 | 
						|
		unsigned extern int short xx;
 | 
						|
	is perfectly good C.
 | 
						|
	
 | 
						|
	On top of that, multiple occurrences of storage_class_specifiers,
 | 
						|
	unsigned_specifiers and size_specifiers are errors, but a second
 | 
						|
	type_specifier should end the decl_specifiers and be treated as
 | 
						|
	the name to be declared (see the thin ice in RM11.1).
 | 
						|
	Such a language is not easily expressed in a grammar; enumeration
 | 
						|
	of the permutations is unattractive. We solve the problem by
 | 
						|
	having a regular grammar for the "soft" items, handling the single
 | 
						|
	occurrence of the type_specifier in the grammar (we have no choice),
 | 
						|
	collecting all data in a `struct decspecs' and turning that data
 | 
						|
	structure into what we want.
 | 
						|
	
 | 
						|
	The existence of declarations like
 | 
						|
		short typedef yepp;
 | 
						|
	makes all hope of writing a specific grammar for typedefs illusory.
 | 
						|
*/
 | 
						|
 | 
						|
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
 | 
						|
	]
 | 
						|
|
 | 
						|
	single_type_specifier(ds) other_specifier(ds)*
 | 
						|
]
 | 
						|
	{do_decspecs(ds);}
 | 
						|
;
 | 
						|
 | 
						|
/* 8.1 */
 | 
						|
other_specifier(register struct decspecs *ds;):
 | 
						|
	[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
 | 
						|
	{	if (ds->ds_sc_given)
 | 
						|
			error("repeated storage class specifier");
 | 
						|
		ds->ds_sc_given = 1;
 | 
						|
		ds->ds_sc = DOT;
 | 
						|
	}
 | 
						|
|
 | 
						|
	[ SHORT | LONG ]
 | 
						|
	{	if (ds->ds_size)
 | 
						|
			error("repeated size specifier");
 | 
						|
		ds->ds_size = DOT;
 | 
						|
	}
 | 
						|
|
 | 
						|
	UNSIGNED
 | 
						|
	{	if (ds->ds_unsigned)
 | 
						|
			error("unsigned specified twice");
 | 
						|
		ds->ds_unsigned = 1;
 | 
						|
	}
 | 
						|
;
 | 
						|
 | 
						|
/* 8.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;}
 | 
						|
;
 | 
						|
 | 
						|
single_type_specifier(register struct decspecs *ds;):
 | 
						|
	%default TYPE_IDENTIFIER	/* this includes INT, CHAR, etc. */
 | 
						|
	{idf2type(dot.tk_idf, &ds->ds_type);}
 | 
						|
|
 | 
						|
	IDENTIFIER
 | 
						|
	{
 | 
						|
		error("%s is not a type identifier", dot.tk_idf->id_text);
 | 
						|
	 	ds->ds_type = error_type;
 | 
						|
		if (dot.tk_idf->id_def) {
 | 
						|
	 		dot.tk_idf->id_def->df_type = error_type;
 | 
						|
	 		dot.tk_idf->id_def->df_sc = TYPEDEF;
 | 
						|
		}
 | 
						|
	}
 | 
						|
|
 | 
						|
	struct_or_union_specifier(&ds->ds_type)
 | 
						|
|
 | 
						|
	enum_specifier(&ds->ds_type)
 | 
						|
;
 | 
						|
 | 
						|
/* 8.3 */
 | 
						|
init_declarator_list(struct decspecs *ds;):
 | 
						|
	init_declarator(ds)
 | 
						|
	[ ',' init_declarator(ds) ]*
 | 
						|
;
 | 
						|
 | 
						|
init_declarator(register struct decspecs *ds;)
 | 
						|
	{
 | 
						|
		struct declarator Dc;
 | 
						|
	}
 | 
						|
:
 | 
						|
	{
 | 
						|
		Dc = null_declarator;
 | 
						|
	}
 | 
						|
[
 | 
						|
	declarator(&Dc)
 | 
						|
	{
 | 
						|
		reject_params(&Dc);
 | 
						|
		declare_idf(ds, &Dc, level);
 | 
						|
	}
 | 
						|
	[
 | 
						|
		initializer(Dc.dc_idf, ds->ds_sc)
 | 
						|
	|
 | 
						|
		{ code_declaration(Dc.dc_idf, (struct expr *) 0, level, ds->ds_sc); }
 | 
						|
	]
 | 
						|
]
 | 
						|
	{remove_declarator(&Dc);}
 | 
						|
;
 | 
						|
 | 
						|
/* 8.6: initializer */
 | 
						|
initializer(struct idf *idf; int sc;)
 | 
						|
	{
 | 
						|
		struct expr *expr = (struct expr *) 0;
 | 
						|
		int globalflag = level == L_GLOBAL ||
 | 
						|
				 (level >= L_LOCAL && sc == STATIC);
 | 
						|
	}
 | 
						|
:
 | 
						|
	{	if (idf->id_def->df_type->tp_fund == FUNCTION)	{
 | 
						|
			error("illegal initialization of function");
 | 
						|
		}
 | 
						|
	}
 | 
						|
	[
 | 
						|
		'='
 | 
						|
	|
 | 
						|
		empty
 | 
						|
		{warning("old-fashioned initialization, insert =");}
 | 
						|
		/*	This causes trouble at declarator and at
 | 
						|
			external_definition, q.v.
 | 
						|
		*/
 | 
						|
	]
 | 
						|
	{	if (globalflag) {
 | 
						|
			struct expr ex;
 | 
						|
			code_declaration(idf, &ex, level, sc);
 | 
						|
	  	}
 | 
						|
	}
 | 
						|
	initial_value(globalflag ? &(idf->id_def->df_type) : (struct type **)0,
 | 
						|
			&expr)
 | 
						|
	{	if (! globalflag) {
 | 
						|
			if (idf->id_def->df_type->tp_fund == FUNCTION)	{
 | 
						|
				free_expression(expr);
 | 
						|
				expr = 0;
 | 
						|
			}
 | 
						|
#ifdef	DEBUG
 | 
						|
			print_expr("initializer-expression", expr);
 | 
						|
#endif	DEBUG
 | 
						|
			code_declaration(idf, expr, level, sc);
 | 
						|
	  	}
 | 
						|
	  	init_idf(idf);
 | 
						|
	}
 | 
						|
;
 | 
						|
 | 
						|
/*
 | 
						|
	Functions yielding pointers to functions must be declared as, e.g.,
 | 
						|
		int (*hehe(par1, par2))() char *par1, *par2;	{}
 | 
						|
	Since the function heading is read as a normal declarator,
 | 
						|
	we just include the (formal) parameter list in the declarator
 | 
						|
	description list dc.
 | 
						|
*/
 | 
						|
declarator(register struct declarator *dc;)
 | 
						|
	{
 | 
						|
		arith count;
 | 
						|
		struct formal *fm = 0;
 | 
						|
	}
 | 
						|
:
 | 
						|
	primary_declarator(dc)
 | 
						|
	[%while(1)			/*	int i (M + 2) / 4;
 | 
						|
						is a function, not an
 | 
						|
						old-fashioned initialization.
 | 
						|
					*/
 | 
						|
		'('
 | 
						|
		formal_list(&fm) ?	/* semantic check later...	*/
 | 
						|
		')'
 | 
						|
		{
 | 
						|
			add_decl_unary(dc, FUNCTION, (arith)0, fm);
 | 
						|
			fm = 0;
 | 
						|
		}
 | 
						|
	|
 | 
						|
		arrayer(&count)
 | 
						|
		{add_decl_unary(dc, ARRAY, count, NO_PARAMS);}
 | 
						|
	]*
 | 
						|
|
 | 
						|
	'*' declarator(dc)
 | 
						|
	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
 | 
						|
;
 | 
						|
 | 
						|
primary_declarator(register struct declarator *dc;) :
 | 
						|
	identifier(&dc->dc_idf)
 | 
						|
|
 | 
						|
	'(' declarator(dc) ')'
 | 
						|
;
 | 
						|
 | 
						|
arrayer(arith *sizep;)
 | 
						|
	{ struct expr *expr; }
 | 
						|
:
 | 
						|
	'['
 | 
						|
		[
 | 
						|
			constant_expression(&expr)
 | 
						|
			{
 | 
						|
				check_array_subscript(expr);
 | 
						|
				*sizep = expr->VL_VALUE;
 | 
						|
				free_expression(expr);
 | 
						|
			}
 | 
						|
		|
 | 
						|
			empty
 | 
						|
			{ *sizep = (arith)-1; }
 | 
						|
		]
 | 
						|
	']'
 | 
						|
;
 | 
						|
 | 
						|
formal_list (struct formal **fmp;)
 | 
						|
:
 | 
						|
	formal(fmp) [ ',' formal(fmp) ]*
 | 
						|
;
 | 
						|
 | 
						|
formal(struct formal **fmp;)
 | 
						|
	{struct idf *idf;	}
 | 
						|
:
 | 
						|
	identifier(&idf)
 | 
						|
	{
 | 
						|
		register struct formal *new = new_formal();
 | 
						|
		
 | 
						|
		new->fm_idf = idf;
 | 
						|
		new->next = *fmp;
 | 
						|
		*fmp = new;
 | 
						|
	}
 | 
						|
;
 | 
						|
 | 
						|
/* Change 2 */
 | 
						|
enum_specifier(register struct type **tpp;)
 | 
						|
	{
 | 
						|
		struct idf *idf;
 | 
						|
		arith l = (arith)0;
 | 
						|
	}
 | 
						|
:
 | 
						|
	ENUM
 | 
						|
	[
 | 
						|
		{declare_struct(ENUM, (struct idf *) 0, tpp);}
 | 
						|
		enumerator_pack(*tpp, &l)
 | 
						|
	|
 | 
						|
		identifier(&idf)
 | 
						|
		[
 | 
						|
			{declare_struct(ENUM, idf, tpp);}
 | 
						|
			enumerator_pack(*tpp, &l)
 | 
						|
		|
 | 
						|
			{apply_struct(ENUM, idf, tpp);}
 | 
						|
			empty
 | 
						|
		]
 | 
						|
	]
 | 
						|
;
 | 
						|
 | 
						|
enumerator_pack(register struct type *tp; arith *lp;) :
 | 
						|
	'{'
 | 
						|
	enumerator(tp, lp)
 | 
						|
	[%while(AHEAD != '}')		/* >>> conflict on ',' */
 | 
						|
		','
 | 
						|
		enumerator(tp, lp)
 | 
						|
	]*
 | 
						|
	','?				/* optional trailing comma */
 | 
						|
	'}'
 | 
						|
	{tp->tp_size = int_size;}
 | 
						|
	/*	fancy implementations that put small enums in 1 byte
 | 
						|
		or so should start here.
 | 
						|
	*/
 | 
						|
;
 | 
						|
 | 
						|
enumerator(struct type *tp; arith *lp;)
 | 
						|
	{
 | 
						|
		struct idf *idf;
 | 
						|
		struct expr *expr;
 | 
						|
	}
 | 
						|
:
 | 
						|
	identifier(&idf)
 | 
						|
	[
 | 
						|
		'='
 | 
						|
		constant_expression(&expr)
 | 
						|
		{
 | 
						|
			*lp = expr->VL_VALUE;
 | 
						|
			free_expression(expr);
 | 
						|
		}
 | 
						|
	]?
 | 
						|
	{declare_enum(tp, idf, (*lp)++);}
 | 
						|
;
 | 
						|
 | 
						|
/* 8.5 */
 | 
						|
struct_or_union_specifier(register struct type **tpp;)
 | 
						|
	{
 | 
						|
		int fund;
 | 
						|
		struct idf *idfX;
 | 
						|
		register struct idf *idf;
 | 
						|
	}
 | 
						|
:
 | 
						|
	[ STRUCT | UNION ]
 | 
						|
	{fund = DOT;}
 | 
						|
	[
 | 
						|
		{
 | 
						|
			declare_struct(fund, (struct idf *)0, tpp);
 | 
						|
		}
 | 
						|
		struct_declaration_pack(*tpp)
 | 
						|
	|
 | 
						|
		identifier(&idfX)	{ idf = idfX; }
 | 
						|
		[
 | 
						|
			{
 | 
						|
				declare_struct(fund, idf, tpp);
 | 
						|
				(idf->id_struct->tg_busy)++;
 | 
						|
			}
 | 
						|
			struct_declaration_pack(*tpp)
 | 
						|
			{
 | 
						|
				(idf->id_struct->tg_busy)--;
 | 
						|
			}
 | 
						|
		|
 | 
						|
			{apply_struct(fund, idf, tpp);}
 | 
						|
			empty
 | 
						|
		]
 | 
						|
	]
 | 
						|
;
 | 
						|
 | 
						|
struct_declaration_pack(register struct type *stp;)
 | 
						|
	{
 | 
						|
		struct sdef **sdefp = &stp->tp_sdef;
 | 
						|
		arith size = (arith)0;
 | 
						|
	}
 | 
						|
:
 | 
						|
	/*	The size is only filled in after the whole struct has
 | 
						|
		been read, to prevent recursive definitions.
 | 
						|
	*/
 | 
						|
	'{'
 | 
						|
	struct_declaration(stp, &sdefp, &size)+
 | 
						|
	'}'
 | 
						|
	{stp->tp_size = align(size, stp->tp_align);}
 | 
						|
;
 | 
						|
 | 
						|
struct_declaration(struct type *stp; struct sdef ***sdefpp; arith *szp;)
 | 
						|
	{struct type *tp;}
 | 
						|
:
 | 
						|
	type_specifier(&tp)
 | 
						|
	struct_declarator_list(tp, stp, sdefpp, szp)
 | 
						|
	[	/*	in some standard UNIX compilers the semicolon
 | 
						|
			is optional, would you believe!
 | 
						|
		*/
 | 
						|
		';'
 | 
						|
	|
 | 
						|
		empty
 | 
						|
		{warning("no semicolon after declarator");}
 | 
						|
	]
 | 
						|
;
 | 
						|
 | 
						|
struct_declarator_list(struct type *tp, *stp;
 | 
						|
			struct sdef ***sdefpp; arith *szp;)
 | 
						|
:
 | 
						|
	struct_declarator(tp, stp, sdefpp, szp)
 | 
						|
	[ ',' struct_declarator(tp, stp, sdefpp, szp) ]*
 | 
						|
;
 | 
						|
 | 
						|
struct_declarator(struct type *tp; struct type *stp;
 | 
						|
			struct sdef ***sdefpp; arith *szp;)
 | 
						|
	{
 | 
						|
		struct declarator Dc;
 | 
						|
		struct field *fd = 0;
 | 
						|
	}
 | 
						|
:
 | 
						|
	{
 | 
						|
		Dc = null_declarator;
 | 
						|
	}
 | 
						|
[
 | 
						|
	declarator(&Dc)
 | 
						|
	{reject_params(&Dc);}
 | 
						|
	bit_expression(&fd)?
 | 
						|
|
 | 
						|
	{Dc.dc_idf = gen_idf();}
 | 
						|
	bit_expression(&fd)
 | 
						|
]
 | 
						|
	{add_sel(stp, declare_type(tp, &Dc), Dc.dc_idf, sdefpp, szp, fd);}
 | 
						|
	{remove_declarator(&Dc);}
 | 
						|
;
 | 
						|
 | 
						|
bit_expression(struct field **fd;)
 | 
						|
	{ struct expr *expr; }
 | 
						|
:
 | 
						|
	{
 | 
						|
		*fd = new_field();
 | 
						|
	}
 | 
						|
	':'
 | 
						|
	constant_expression(&expr)
 | 
						|
	{
 | 
						|
		(*fd)->fd_width = expr->VL_VALUE;
 | 
						|
		free_expression(expr);
 | 
						|
#ifdef NOBITFIELD
 | 
						|
		error("bitfields are not implemented");
 | 
						|
#endif NOBITFIELD
 | 
						|
	}
 | 
						|
;
 | 
						|
 | 
						|
/* 8.7 */
 | 
						|
cast(struct type **tpp;)	{struct declarator Dc;} :
 | 
						|
	{Dc = null_declarator;}
 | 
						|
	'('
 | 
						|
	type_specifier(tpp)
 | 
						|
	abstract_declarator(&Dc)
 | 
						|
	')'
 | 
						|
	{*tpp = declare_type(*tpp, &Dc);}
 | 
						|
	{remove_declarator(&Dc);}
 | 
						|
;
 | 
						|
 | 
						|
/*	This code is an abject copy of that of 'declarator', for lack of
 | 
						|
	a two-level grammar.
 | 
						|
*/
 | 
						|
abstract_declarator(register struct declarator *dc;)
 | 
						|
	{arith count;}
 | 
						|
:
 | 
						|
	primary_abstract_declarator(dc)
 | 
						|
	[
 | 
						|
		'(' ')'
 | 
						|
		{add_decl_unary(dc, FUNCTION, (arith)0, NO_PARAMS);}
 | 
						|
	|
 | 
						|
		arrayer(&count)
 | 
						|
		{add_decl_unary(dc, ARRAY, count, NO_PARAMS);}
 | 
						|
	]*
 | 
						|
|
 | 
						|
	'*' abstract_declarator(dc)
 | 
						|
	{add_decl_unary(dc, POINTER, (arith)0, NO_PARAMS);}
 | 
						|
;
 | 
						|
 | 
						|
primary_abstract_declarator(struct declarator *dc;) :
 | 
						|
[%if (AHEAD == ')')
 | 
						|
	empty
 | 
						|
|
 | 
						|
	'(' abstract_declarator(dc) ')'
 | 
						|
]
 | 
						|
;
 | 
						|
 | 
						|
empty:
 | 
						|
;
 | 
						|
 | 
						|
/* 8.8 */
 | 
						|
/* included in the IDENTIFIER/TYPE_IDENTIFIER mechanism */
 |