⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 norm.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#) norm.c 1.3 1/27/86 17:49:14 */ /*ident	"@(#)cfront:src/norm.c	1.3" *//************************************************************************	C++ source for cfront, the C++ compiler front-end	written in the computer science research center of Bell Labs	Copyright (c) 1984 AT&T, Inc. All Rights Reserved	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.norm.c:	"normalization" handles problems which could have been handled	by the syntax analyser; but has not been done. The idea is	to simplify the grammar and the actions accociated with it,	and to get a more robust error handling****************************************************************************/#include "cfront.h"#include "size.h"extern void syn_init();void syn_init(){	any_type = new basetype(ANY,0);	PERM(any_type);	dummy = new expr(DUMMY,0,0);	PERM(dummy);	dummy->tp = any_type;	zero = new expr(ZERO,0,0);	PERM(zero);}int stcount;char* make_name(TOK c){	char* s = new char[8];	/* as it happens: fits in two words */	if (99999 <= ++stcount) error('i',"too many generated names");	s[0] = '_';	s[1] = c;	int count = stcount;	int i = 2;	if (10000 <= count) {		s[i++] = '0' + count/10000;		count %= 10000;	}	if (1000 <= count) {		s[i++] = '0' + count/1000;		count %= 1000;	}	else if (2<i) s[i++] = '0';	if (100 <= count) {		s[i++] = '0' + count/100;		count %= 100;	}	else if (2<i) s[i++] = '0';	if (10 <= count) {		s[i++] = '0' + count/10;		count %= 10;	}	else if (2<i) s[i++] = '0';	s[i++] = '0' + count;	s[i] = 0;	return s;}Pbase basetype.type_adj(TOK t){	switch (base) {	case COBJ:	case EOBJ:	{	Pbase bt = new basetype(0,0);		*bt = *this;		DEL(this);		this = bt;	}	}				if (b_xname) {		if (base)			error("badBT:%n%k",b_xname,t);		else {			base = TYPE;			b_name = b_xname;		}		b_xname = 0;	}	switch (t) {	case TYPEDEF:	b_typedef = 1;	break;	case INLINE:	b_inline = 1;	break;	case VIRTUAL:	b_virtual = 1;	break;	case CONST:	b_const = 1;	break;	case UNSIGNED:	b_unsigned = 1;	break;	case SHORT:	b_short = 1;	break;	case LONG:	b_long = 1;	break;	case FRIEND:	case OVERLOAD:	case EXTERN:	case STATIC:	case AUTO:	case REGISTER:		if (b_sto)			error("badBT:%k%k",b_sto,t);		else			b_sto = t;		break;	case VOID:	case CHAR:	case INT:	case FLOAT:	case DOUBLE:		if (base)			error("badBT:%k%k",base,t);		else			base = t; 		break;	default:		error('i',"basetype.type_adj(%k)",t);	}	return this;}Pbase basetype.name_adj(Pname n){	if (b_xname) {		if (base)			error("badBT:%n%n",b_xname,n);		else {			base = TYPE;			b_name = b_xname;		}		b_xname = 0;	}	b_xname = n;	return this;}Pbase basetype.base_adj(Pbase b){	Pname bn = b->b_name;	switch (base) {	case COBJ:	case EOBJ:		error("NX after%k%n",base,b_name);		return this;	}	if (base) {		if (b_name)			error("badBT:%k%n%k%n",base,b_name,b->base,bn);		else			error("badBT:%k%k%n",base,b->base,bn);	}	else {		base = b->base;		b_name = bn;		b_table = b->b_table;	}	return this;}Pbase basetype.check(Pname n)/*	"n" is the first name to be declared using "this"	check the consistency of "this"	and use "b_xname" for "n->string" if possible and needed*/{	b_inline = 0;	b_virtual = 0;//fprintf(stderr,"check n: %d %s n_oper %d b: %d %d %s\n",n,(n)?n->string:"",n?n->n_oper:0,this,base,(b_name)?b_name->string:"");fflush(stderr);	if (b_xname && (n->tp || n->string)) {		if (base)			error("badBT:%k%n",base,b_xname);		else {			base = TYPE;			b_name = b_xname;		}		b_xname = 0;	}	if (b_xname) {		if (n->string)			error("twoNs inD:%n%n",b_xname,n);		else {			n->string = b_xname->string;			b_xname->hide();		}		b_xname = 0;	}	if (ccl==0	&& n	&& n->n_oper==TNAME	&& n->n_qualifier==0	&& n->string) {	// hide type name		Pname nx = ktbl->look(n->string,0);		if (nx) nx->hide();	}	switch (base) {	case 0:		base = INT;		break;	case EOBJ:	case COBJ:		if (b_name->base == TNAME)			error('i',"TN%n inCO %d",b_name,this);	}	if (b_long || b_short) {		TOK sl = (b_short) ? SHORT : LONG;		if (b_long && b_short) error("badBT:long short%k%n",base,n);		if (base != INT)			error("badBT:%k%k%n",sl,base,n);		else			base = sl;		b_short = b_long = 0;	}	if (b_typedef && b_sto) error("badBT:typedef%k%n",b_sto,n);	b_typedef = b_sto = 0;	if (Pfctvec_type == 0) return this;	if (b_const) {		if (b_unsigned) {			switch (base) {			default:				error("badBT: unsigned const %k%n",base,n);				b_unsigned = 0;			case LONG:			case SHORT:			case INT:			case CHAR:				return this;			}		}		return this;	}	else if (b_unsigned) {		switch (base) {		case LONG:			delete this;			return ulong_type;		case SHORT:			delete this;			return ushort_type;		case INT:			delete this;			return uint_type;		case CHAR:			delete this;			return uchar_type;		default:			error("badBT: unsigned%k%n",base,n);			b_unsigned = 0;			return this;		}	}	else {		switch (base) {		case LONG:			delete this;			return long_type;		case SHORT:			delete this;			return short_type;		case INT:			if (this != int_type) delete this;			return int_type;		case CHAR:			delete this;			return char_type;		case VOID:			delete this;			return void_type;		case TYPE:			/* use a single base saved in the keyword *///fprintf(stderr,"type %d bn %d %s q %d\n",this,b_name,b_name->string,b_name->n_qualifier);			if (b_name->n_qualifier) {				delete this;				return (Pbase)b_name->n_qualifier;			}			else {				PERM(this);				b_name->n_qualifier = (Pname)this;				return this;			}		default:			return this;		}	}}Pname basetype.aggr()/*	"type SM" seen e.g.	struct s {};				class x;				enum e;				int tname;				friend cname;				friend class x;				int;	convert		union { ... };	into		union name { ... } name ;*/{	Pname n;	if (b_xname) {		if (base) {			Pname n = new name(b_xname->string);			b_xname->hide();			b_xname = 0;			return n->normalize(this,0,0);		}		else {			base = TYPE;			b_name = b_xname;			b_xname = 0;		}	}	switch (base) {	case COBJ:	{	Pclass cl = (Pclass)b_name->tp;		char* s = cl->string;/*fprintf(stderr,"COBJ (%d %s) -> (%d %d) ->(%d %d)\n",this,b_name->string,b_name,b_name->base,cl,cl->base);*/		if (b_name->base == TNAME) error('i',"TN%n inCO",b_name);		if (b_const) error("const%k%n",cl->csu,b_name);		if (cl->c_body == 2) {	/* body seen */			if (s[0]=='_' && s[1]=='C') {				char* ss = new char[5];				Pname obj = new name(ss);				if (cl->csu == UNION) {					strcpy(ss,s);					ss[1] = 'O';					cl->csu = ANON;					return obj->normalize(this,0,0);				}				error('w',"un-usable%k ignored",cl->csu);			}			cl->c_body = 1;			return b_name;		}		else {	/* really a typedef for cfront only: class x; */			if (b_sto == FRIEND) goto frr;			return 0;		}	}	case EOBJ:	{	Penum en = (Penum)b_name->tp;/*fprintf(stderr,"EOBJ (%d %s) -> (%d %d) ->(%d %d)\n",this,b_name->string,b_name,b_name->base,en,en->base);*/		if (b_name->base == TNAME) error('i',"TN%n in enumO",b_name);		if (b_const) error("const enum%n",b_name);		if (en->e_body == 2) {			en->e_body = 1;			return b_name;		}		else {			if (b_sto == FRIEND) goto frr;			return 0;		}	}	default:		if (b_typedef) error('w',"illegal typedef ignored");		if (b_sto == FRIEND) {		frr:			Pname fr = ktbl->look(b_name->string,0);			if (fr == 0) error('i',"cannot find friend%n",b_name);			n = new name(b_name->string);			n->n_sto = FRIEND;			n->tp = fr->tp;			return n;		}		else {			n = new name(make_name('D'));			n->tp = any_type;			error('w',"NX inDL");			return n;		}	}}void name.hide()/*	hide "this": that is, "this" should not be a keyword in this scope*/{//error('d',"hide%n %d %k tp %d",this,this,base,tp);	if (base != TNAME) return;	if (n_key == 0) {//error('d',"ll %d bl %d base %k",lex_level,bl_level,base);		if (lex_level == bl_level) {			if (this->base != TNAME)				error("%n redefined",this);			else {				// is it a CN?				error('w',"%n redefined",this);			}		}		modified_tn = new name_list(this,modified_tn);		n_key = HIDDEN;	}}void set_scope(Pname tn)/*	enter the scope of class tn after seeing "tn.f"*/{	if (tn->base != TNAME) error('i',"set_scope: not aTN %d %d",tn,tn->base);	Pbase b = (Pbase)tn->tp;	if (b->b_name->tp->base != CLASS) error('i',"T of%n not aC (%k)",tn,b->b_name->tp->base);	Pclass cl = (Pclass)b->b_name->tp;	for (Plist l=cl->tn_list; l; l=l->l) {		Pname n = l->f;		n->n_key = (n->lex_level) ? 0 : HIDDEN;//error('d',"set_scope%n %d",n,n->n_key);		modified_tn = new name_list(n,modified_tn);	}}void restore(){	for (Plist l=modified_tn; l; l=l->l) {		Pname n = l->f;		n->n_key =  (n->lex_level <= bl_level) ? 0 : HIDDEN;//error('d',"restore%n %d",n,n->n_key);	}}Pbase start_cl(TOK t, Pname c, Pname b){	if (c == 0) c = new name(make_name('C'));//error('d',"c: %d %s",c->base,c->string);	Pname n = c->tname(t);			/* t ignored */	n->where = curloc;	Pbase bt = (Pbase)n->tp;		/* COBJ */	if (bt->base != COBJ) {		error("twoDs of%n:%t andC",n,bt);		error('i', "can't recover from previous errors");	}	Pclass occl = ccl;	ccl = (Pclass)bt->b_name->tp;		/* CLASS */	if (ccl->defined) {		error("C%n defined twice");		ccl->defined |= IN_ERROR;	}	ccl->defined |= DEF_SEEN;	if (ccl->in_class = occl) occl->tn_list = modified_tn;	// save  mod-list	modified_tn = 0;	ccl->string = n->string;	ccl->csu = t;	if (b) ccl->clbase = b->tname(t);	return bt;	}void end_cl(){	Pclass occl = ccl->in_class;	Plist ol = occl ? occl->tn_list : 0;	// saved modified name list	ccl->c_body = 2;	if (modified_tn) {	// export nested class names to outer scope:		Plist local = 0;		for (Plist l=modified_tn, nl=0; l; l=nl) {			nl = l->l;			Pname n = l->f;			if (ktbl->look(n->string,0)) {				// add it to enclosing class's modified name list				l->l = ol;				ol = l;			}			else {	// retain it in this class's modified name list				l->l = local;				local = l;			}		}		if (ccl->tn_list = modified_tn = local) restore();	}	modified_tn = ol;	// restore mod-list (possibly modified)	ccl = occl;}Pbase end_enum(Pname n, Pname b){	if (n == 0) n = new name(make_name('E'));	n = n->tname(ENUM);	Pbase bt = (Pbase)n->tp;	if (bt->base != EOBJ) {		error("twoDs of%n:%t and enum",n,bt);		error('i', "can't recover from previous errors");	}	Penum en = (Penum)bt->b_name->tp;	en->e_body = 2;	en->mem = name_unlist((class nlist *)b);	if (en->defined) {		error("enum%n defined twice",n);		en->defined |= IN_ERROR;	}	en->defined |= DEF_SEEN;	return bt;}Pname name.tdef()/*	typedef "this"*/{//error('d',"tdef%n",this);	Pname n = ktbl->insert(this,0);	if (tp == 0) error('i',"typedef%n tp==0",this);	n->base = base = TNAME;	PERM(n);	PERM(tp);	modified_tn = new name_list(n,modified_tn);	return n;}Pname name.tname(TOK csu)/*	"csu" "this" seen, return typedef'd name for "this"	return	(TNAME,x)	x:	(COBJ,y)	y:	(NAME,z)	z:	(CLASS,ae);*/{//fprintf(stderr,"tname %s %d ll %d\n",string,this,lex_level);	switch (base) {	case TNAME:		return this;	case NAME:	{	Pname tn = ktbl->insert(this,0);//fprintf(stderr,"tname tn %s %d ll %d (mod %d)\n",tn->string,tn,tn->lex_level,modified_tn);		Pname on = new name;		tn->base = TNAME;		tn->lex_level = lex_level;		modified_tn = new name_list(tn,modified_tn);		tn->n_list = n_list = 0;		string = tn->string;		*on = *this;		switch (csu) {		case ENUM:			tn->tp = new basetype(EOBJ,on);			on->tp = new enumdef(0);			break;		default:			on->tp =  new classdef(csu,0);			Pclass(on->tp)->string = tn->string;			tn->tp = new basetype(COBJ,on);			Pbase(tn->tp)->b_table = Pclass(on->tp)->memtbl;		}		PERM(tn);		PERM(tn->tp);		PERM(on);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -