📄 cgen.c
字号:
#include "globals.h"
#include "symtab.h"
#include "cgen.h"
#include "string.h"
static int currenttemp=0;
static int currentlabel=0;
static int currentline=0;
char*c=NULL;
void codeGen(TreeNode*syntaxTree);
void cGen(TreeNode*tree);
void genStmt(TreeNode*tree);
void genExp(TreeNode*tree);
int connect(char**c1,char*c2);
int spaceconnect(char**c1,char*c2);
int lineconnect(char**c1,char*c2);
char*newtemp();
char*newlabel(char**l);
void newline();
void codeGen(TreeNode*syntaxTree)
{
cGen(syntaxTree);
fprintf(code,"%s",c);
}
void cGen(TreeNode*tree)
{
if (tree != NULL)
{
switch (tree->nodekind)
{
case StmtK:
genStmt(tree);
break;
case ExpK:
genExp(tree);
break;
default:
break;
}
cGen(tree->sibling);
}
}
void genStmt(TreeNode*tree)
{
TreeNode * p1, * p2, * p3;
char*label1=NULL;
char*label2=NULL;
char*label3=NULL;
char*label4=NULL;
char*l1=NULL;
char*l2=NULL;
char*l3=NULL;
char*l4=NULL;
switch (tree->kind.stmt)
{
case IfK:
p1=tree->child[0];
p2=tree->child[1];
if(tree->child[2]==NULL)
{
label1=newlabel(&l1);
label2=newlabel(&l2);
label3=newlabel(&l3);
newline();
spaceconnect(&c,label1);
cGen(p1);
newline();
spaceconnect(&c,"if");
spaceconnect(&c,p1->tempname);
spaceconnect(&c,"goto");
spaceconnect(&c,l2);
newline();
spaceconnect(&c,"goto");
spaceconnect(&c,l3);
newline();
spaceconnect(&c,label2);
cGen(p2);
newline();
spaceconnect(&c,label3);
}
else
{
p3=tree->child[2];
label1=newlabel(&l1);
label2=newlabel(&l2);
label3=newlabel(&l3);
label4=newlabel(&l4);
newline();
spaceconnect(&c,label1);
cGen(p1);
newline();
spaceconnect(&c,"if");
spaceconnect(&c,p1->tempname);
spaceconnect(&c,"goto");
spaceconnect(&c,l2);
newline();
spaceconnect(&c,"goto");
spaceconnect(&c,l3);
newline();
spaceconnect(&c,label2);
cGen(p2);
newline();
spaceconnect(&c,"goto");
spaceconnect(&c,l4);
newline();
spaceconnect(&c,label3);
cGen(p3);
newline();
spaceconnect(&c,label4);
}
break;
case RepeatK:
p1=tree->child[0];
p2=tree->child[1];
label1=newlabel(&l1);
label2=newlabel(&l2);
newline();
spaceconnect(&c,label1);
cGen(p1);
cGen(p2);
newline();
spaceconnect(&c,"if");
spaceconnect(&c,p2->tempname);
spaceconnect(&c,"goto");
spaceconnect(&c,l2);
newline();
spaceconnect(&c,"goto");
spaceconnect(&c,l1);
newline();
spaceconnect(&c,label2);
break;
case AssignK:
cGen(tree->child[0]);
newline();
spaceconnect(&c,tree->attr.name);
connect(&c,":=");
connect(&c,tree->child[0]->tempname);
break;
case ReadK:
newline();
spaceconnect(&c,"read");
spaceconnect(&c,tree->attr.name);
break;
case WriteK:
cGen(tree->child[0]);
newline();
spaceconnect(&c,"write");
spaceconnect(&c,tree->child[0]->tempname);
break;
case WhileK:
p1=tree->child[0];
p2=tree->child[1];
label1=newlabel(&l1);
label2=newlabel(&l2);
label3=newlabel(&l3);
newline();
spaceconnect(&c,label1);
cGen(p1);
newline();
spaceconnect(&c,"goto");
spaceconnect(&c,l2);
newline();
spaceconnect(&c,label2);
cGen(p2);
newline();
spaceconnect(&c,"if");
spaceconnect(&c,p2->tempname);
spaceconnect(&c,"goto");
spaceconnect(&c,l1);
newline();
spaceconnect(&c,"goto");
spaceconnect(&c,l3);
newline();
spaceconnect(&c,label3);
break;
default:
break;
}
}
void genExp(TreeNode*tree)
{
TreeNode * p1, * p2;
char*op=NULL;
char*t1=NULL;
char*t2=NULL;
int n=0;
switch (tree->kind.exp)
{
case OpK:
p1=tree->child[0];
if(tree->attr.op==NOT)
{
cGen(p1);
if(p1->kind.exp==OpK)
{
t1=newtemp();
newline();
spaceconnect(&c,t1);
connect(&c,"=");
connect(&c,p1->tempname);
}
else
{
t1=p1->tempname;
}
tree->tempname=(char*)malloc(3*sizeof
(char));
strcpy(tree->tempname,"not ");
connect(&tree->tempname,t1);
}
else if(tree->attr.op==OR||tree->attr.op==AND||
tree->attr.op==PLUS||tree->attr.op==MINUS||
tree->attr.op==TIMES||tree->attr.op==OVER||
tree->attr.op==LT||tree->attr.op==EQ||
tree->attr.op==GT||tree->attr.op==NGT||
tree->attr.op==NLT)
{
p2=tree->child[1];
switch (tree->attr.op)
{
case OR:
connect(&op," or ");
break;
case AND:
connect(&op," and ");
break;
case PLUS:
connect(&op,"+");
break;
case MINUS:
connect(&op,"-");
break;
case TIMES:
connect(&op,"*");
break;
case OVER:
connect(&op,"/");
break;
case LT:
connect(&op,"<");
break;
case EQ:
connect(&op,"=");
break;
case GT:
connect(&op,">");
break;
case NGT:
connect(&op,"<=");
break;
case NLT:
connect(&op,">=");
break;
default:
break;
}
cGen(p1);
cGen(p2);
if(p1->kind.exp==OpK||p2->kind.exp==OpK)
{
if(p1->kind.exp==OpK)
{
t1=newtemp();
newline();
spaceconnect(&c,t1);
connect(&c,"=");
connect(&c,p1->tempname);
}
else t1=p1->tempname;
if(p2->kind.exp==OpK)
{
t2=newtemp();
newline();
spaceconnect(&c,t2);
connect(&c,"=");
connect(&c,p2->tempname);
}
else t2=p2->tempname;
}
else
{
t1=p1->tempname;
t2=p2->tempname;
}
connect(&tree->tempname,t1);
connect(&tree->tempname,op);
connect(&tree->tempname,t2);
}
break;
case ConstK:
tree->tempname=(char*)malloc(10*sizeof(char));
itoa(tree->attr.val,tree->tempname,10);
break;
case IdK:
n=strlen(tree->attr.name);
tree->tempname=(char*)malloc(n*sizeof(char));
strcpy(tree->tempname,tree->attr.name);
break;
case StrK:
n=strlen(tree->attr.str);
n=n+2;
tree->tempname=(char*)malloc(n*sizeof(char));
strcpy(tree->tempname,"\"");
strcat(tree->tempname,tree->attr.str);
strcat(tree->tempname,"\"");
break;
case BK:
tree->tempname=(char*)malloc(sizeof(char));
if(tree->attr.val>1) strcpy(tree->tempname,"1");
else strcpy(tree->tempname,"0");
break;
default:
break;
}
}
int connect(char**c1,char*c2)
{
int l1,l2,l=0;
char*buf;
if(*c1==NULL)
{
*c1=(char*)malloc(sizeof(char));
strcpy(*c1,"");
}
if(c2==NULL)
{
c2=(char*)malloc(sizeof(char));
strcpy(c2,"");
}
l1=strlen(*c1);
l2=strlen(c2);
l=l1+l2;
buf=(char*)malloc(l*sizeof(char));
strcpy(buf,*c1);
strcat(buf,c2);
*c1=buf;
return l;
}
int spaceconnect(char**c1,char*c2)
{
int l1,l2,l=0;
char*buf;
if(*c1==NULL)
{
*c1=(char*)malloc(sizeof(char));
strcpy(*c1,"");
}
if(c2==NULL)
{
c2=(char*)malloc(sizeof(char));
strcpy(c2,"");
}
l1=strlen(*c1);
l2=strlen(c2);
l=l1+l2+1;
buf=(char*)malloc(l*sizeof(char));
strcpy(buf,*c1);
strcat(buf," ");
strcat(buf,c2);
*c1=buf;
return l;
}
int lineconnect(char**c1,char*c2)
{
int l1,l2,l=0;
char*buf;
if(*c1==NULL)
{
*c1=(char*)malloc(sizeof(char));
strcpy(*c1,"");
}
if(c2==NULL)
{
c2=(char*)malloc(sizeof(char));
strcpy(c2,"");
}
l1=strlen(*c1);
l2=strlen(c2);
l=l1+l2+1;
buf=(char*)malloc(l*sizeof(char));
strcpy(buf,*c1);
strcat(buf,"\n");
strcat(buf,c2);
*c1=buf;
return l;
}
char*newtemp()
{
char*n=NULL;
char*nt=NULL;
nt=(char*)malloc(4*sizeof(char));
n=(char*)malloc(3*sizeof(char));
strcpy(nt,"t");
itoa(currenttemp,n,10);
currenttemp++;
strcat(nt,n);
return nt;
}
char*newlabel(char**l)
{
char*n=NULL;
char*nl=NULL;
nl=(char*)malloc(10*sizeof(char));
n=(char*)malloc(3*sizeof(char));
strcpy(nl,"Label L");
itoa(currentlabel++,n,10);
strcat(nl,n);
*l=(char*)malloc(4*sizeof(char));
strcpy(*l,"L");
strcat(*l,n);
return nl;
}
void newline()
{
char*n=NULL;
char*nl=NULL;
nl=(char*)malloc(5*sizeof(char));
n=(char*)malloc(4*sizeof(char));
itoa(currentline++,n,10);
strcpy(nl,n);
strcat(nl,")");
lineconnect(&c,nl);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -