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

📄 stmt.c

📁 unix环境下实现的cmm语言编译器
💻 C
字号:
/*stmt.c:对语句进行语法分析*/#include "cmm.h"struct code codehead = {Start};Code codelist = &codehead;static void ifstmt(int lab, int loop, int lev);static void retcode(Tree p);static Tree conditional(int tok);static void whilestmt(int lab, int lev);static int equal(Symbol lprime, Symbol dst);/*code:建立代码表结点,并将它串成一个链表*/Code code(int kind){	Code cp;	NEW(cp, FUNC);	cp->kind = kind;	cp->next = NULL;	codelist->next = cp;	cp->prev = codelist;	codelist = cp;	return cp;}/*statement: *			[expression]; *			if '(' expression ')' statement *			if '(' expression ')' statement else statement  *			while '(' expression ')' statement  *			break; *			continue; *			return [expression ]; *			compound-statement *statement分析语句,loop表示最近的while语句的标号。 *lev为复合语句嵌套的层数*/void statement(int loop, int lev){	float ref = refinc;		DEBUG(fprint(2,"statement begin: %d\n", lev));	switch(t) {	case IF:		ifstmt(genlabel(2), loop, lev+1); /*if语句可能需要二个标号*/		break;	case WHILE:		whilestmt(genlabel(3), lev+1);		break;	case BREAK:		walk(NULL, 0, 0);		if(loop) /*break语句将跳出当前的循环*/			branch(loop+2);		else 			error("illegal break statement\n");		t = gettoken();		expect(';');		break;	case CONTINUE:		walk(NULL, 0, 0);		if(loop) /*continue跳到while语句的条件表达式处*/			branch(loop+1);		else			error("illegal continue statement\n");		t = gettoken();		expect(';');		break;	case RETURN:{ Type rty = freturn(cfunc->type);			t = gettoken();			if(t != ';') {				if(rty == voidtype) {					error("extraneous return value\n");					expr(0);					retcode(NULL);				}else					retcode(expr(0));			}else {				if(rty != voidtype && rty != inttype)					warning("missing return value\n");				retcode(NULL);						}			branch(cfunc->u.f.label);		}		expect(';');		break;	case '{':	compound(loop, lev+1);break;	case ';':	t = gettoken(); break;	default:		if(kind[t] != ID) {			error("unrecognized statement\n");			t = gettoken();		}else { /*表达式语句*/			Tree e = expr(0);			walk(e, 0, 0);			deallocate(STMT);		}		expect(';');		break;	}	if(kind[t] != ID && kind[t] != IF	&& t != '}' && t != EOI ){		static char stop[] = {IF, ID,'}', 0};	 	error("illegal statement termination\n");		skipto(0,stop);	}	refinc = ref;	DEBUG(fprint(2,"statement end: %d\n\n", lev));}static void ifstmt(int lab, int loop, int lev){	DEBUG(fprint(2,"if statement begin: %d\n", lev));	t = gettoken();	expect('(');	walk(conditional(')'), 0, lab); /*为if语句生成当条件为假时跳转至lab的dag									 *并将其添加到代码表中*/	refinc /=2.0;	/*if分支使引用频率减半*/	statement(loop, lev);	if(ELSE == t) {		branch(lab+1);		t = gettoken();		definelab(lab);		statement(loop, lev);		if(findlabel(lab+1)->ref)			definelab(lab+1);	}else		definelab(lab);	DEBUG(fprint(2,"if statement end: %d\n", lev));}/*definelab生成标号,并将其添加到代码表*/void definelab(int lab){	Symbol p = findlabel(lab);	assert(lab);	Code cp;	walk(NULL, 0, 0);	code(Label)->u.forest = newnode(LABELV,NULL,NULL,p);	/*删除连续的标号语句,将其做为一个标号使用*/	for ( cp = codelist->prev; cp->kind <= Label; cp = cp->prev) {		if (Label == cp->kind		&& LABELV == cp->u.forest->op		&& !equal(cp->u.forest->syms[0],p)){			equatelab(cp->u.forest->syms[0], p);			assert(cp->prev);				assert(cp->next);			cp->prev->next = cp->next;			cp->next->prev = cp->prev;		}	}}/*将对标号old引用等价于对标号new引用*/void equatelab(Symbol old, Symbol new){		assert(NULL == old->u.l.equatedto);	old->u.l.equatedto = new; /*equatedto将等价标号连接成一个单向的链*/	new->ref++;}/*jump生成跳转的代码结点*/Node jump(int lab){	Symbol p = findlabel(lab);	p->ref++;	return newnode(JUMPV,newnode(ADDRGP, NULL, NULL,p),			NULL, NULL);}static int equal(Symbol lprime, Symbol dst){	assert(dst && lprime);	for ( ; dst; dst = dst->u.l.equatedto)		if (lprime == dst)			return 1;	return 0;}/*branch生成跳转到标号lab的语句*/void branch(int lab){	Code cp;	Symbol p = findlabel(lab);		assert(lab);	walk(NULL, 0, 0);	code(Label)->u.forest = jump(lab);	/*删除跳转代码前的标号*/	for (cp = codelist->prev; cp->kind < Label;)		cp = cp->prev;	while (Label == cp->kind		&& LABELV == cp->u.forest->op 		&& !equal(cp->u.forest->syms[0], p)) {		equatelab(cp->u.forest->syms[0], p); 		assert(cp->next);		assert(cp->prev);		cp->prev->next = cp->next;		cp->next->prev = cp->prev;		cp = cp->prev;		while(cp->kind < Label)			cp = cp->prev;		}	if(Jump == cp->kind) { /*删除跳转代码后的代码,其为不可达代码*/		p->ref--;		codelist = codelist->prev;		codelist->next = NULL;	}else		codelist->kind = Jump;}/*retcode为return语句的表达式生成代码结点*/static void retcode(Tree p){	Type ty;	if(NULL == p)		return;	p = pointer(p);	ty = assign(freturn(cfunc->type), p);	if(NULL == ty) {		error("illegal return type; found '%t' expected '%'\n",		p->type, freturn(cfunc->type));		return;	}	p = cast(p, ty);	p = cast(p, promote(p->type));	walk(tree(RET+ttob(p->type), p->type, p, NULL), 0, 0);}static Tree conditional(int tok){	Tree e = expr(tok);	return cond(e);}/*whilestmt处理while语句*/static void whilestmt(int lab, int lev){	Tree e;	DEBUG(fprint(2,"while statement begin:%d\n", lev));	refinc *= 10.0; /*循环语句里的引用频率将提高10.0*/	t = gettoken();	expect('(');	walk(NULL, 0,0);	e = texpr(conditional,')',FUNC);	branch(lab+1);	definelab(lab);	statement(lab, lev);	definelab(lab+1);	walk(e, lab, 0);	if(findlabel(lab+2)->ref)		definelab(lab+2);	DEBUG(fprint(2,"while statement end:%d\n", lev));}

⌨️ 快捷键说明

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