📄 stmt.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 + -