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

📄 cgen.c

📁 tiny 编译器程序的设计 修改了原作者的程序 现在能生成中间代码
💻 C
字号:
#include "globals.h"
#include "cgen.h"
typedef enum{
ADD,SUB,MULT,DIV,EQC,READC,WRITEC,RETURNC,ASSIG,LABEL,JUMP,JUMP0,JUMPN0}CodeKind;
typedef struct AddressRec{char* name;int dataoff;}*address;
typedef struct ARGrecordRec{
  enum{ValueForm,LabelForm,AddrForm,TddrForm} form;
  union{
  int value;
  int label;
  address addr;}atr;
} *ARGrecord;
static int tempcn=0;
static int label=0;
ARGrecord GenVar(TreeNode *tree)
{ ARGrecord L;
   L=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
   L->form=AddrForm;
   L->atr.addr=(address)malloc(sizeof(struct AddressRec));
   L->atr.addr->name=tree->attr.name;
   L->atr.addr->dataoff=st_lookup(tree->attr.name);
   return L;
}//为变量声称arg结构。

ARGrecord NewTemp()
{ ARGrecord L;
  L=(ARGrecord)malloc(sizeof(ARGrecord));
  L->form=TddrForm;
  L->atr.addr=(address)malloc(sizeof(struct AddressRec));
  L->atr.addr->dataoff=tempcn;
  tempcn++;
  return L;
}//临时变量

ARGrecord ARGvalue(int value)
{ ARGrecord L;
 L=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
 L->form=ValueForm;
 L->atr.value=value;
 return L;
}//为值定义arg结构

ARGrecord ARGlabel()
{ ARGrecord L;
  L=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
  L->form=LabelForm;
  L->atr.label=label;
  label++;
  return L;
}


ARGrecord genexp(TreeNode *tree)
{
  TreeNode *p1,*p2;
  char *str="";
  ARGrecord Larg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
  rarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
  arg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
  temp=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
  TokenType op;
  switch(tree->kind.exp){
  case ConstK:
	  Larg=ARGvalue(tree->attr.val);
      return Larg;
      break;
  case IdK:
      Larg=GenVar(tree);
      return Larg;
      break;
  case OpK:
      p1=tree->child[0];
      p2=tree->child[1];
      Larg=genexp(p1);
      rarg=genexp(p2);
      op=tree->attr.op;
	  switch(op)
	  {case  EQ:str="=";break;
	   case  LT:str="<";break;
	   case MINUS: str="-";break;
	   case PLUS: str="+";break;
	   case  TIMES:str="*";break;
	   case  OVER: str="/";break;
	   
	   default:  break;
	  }
      temp=NewTemp();
	  //根据3*3,选择9种情况进行返回。
	  if(Larg->form==ValueForm&&rarg->form==ValueForm)
      fprintf(code,"%s %d %d %s%d\n",str,Larg->atr.value ,rarg->atr.value,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==ValueForm&&rarg->form==AddrForm)
      fprintf(code,"%s %d %s %s%d\n",str,Larg->atr.value ,rarg->atr.addr->name,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==AddrForm&&rarg->form==ValueForm)
      fprintf(code,"%s %s %d %s%d\n",str,Larg->atr.addr->name ,rarg->atr.value,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==AddrForm&&rarg->form==AddrForm)
      fprintf(code,"%s %s %s %s%d\n",str,Larg->atr.addr->name ,rarg->atr.addr->name,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==AddrForm&&rarg->form==TddrForm)
      fprintf(code,"%s %s %s%d %s%d\n",str,Larg->atr.addr->name ,"T",rarg->atr.addr->dataoff,
        "T",temp->atr.addr->dataoff);
	   if(Larg->form==ValueForm&&rarg->form==TddrForm)
      fprintf(code,"%s %d %s%d %s%d\n",str,Larg->atr.value ,"T",rarg->atr.addr->dataoff,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==TddrForm&&rarg->form==AddrForm)
      fprintf(code,"%s %s%d %s %s%d\n",str,"T",Larg->atr.addr->dataoff ,rarg->atr.addr->name,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==TddrForm&&rarg->form==ValueForm)
      fprintf(code,"%s %s%d %d %s%d\n",str,"T",Larg->atr.addr->dataoff ,rarg->atr.value,
        "T",temp->atr.addr->dataoff);
	  if(Larg->form==TddrForm&&rarg->form==TddrForm)
      fprintf(code,"%s %s%d %s%d %s%d\n",str,"T",Larg->atr.addr->dataoff,"T",rarg->atr.addr->dataoff,
        "T",temp->atr.addr->dataoff);

      arg=temp;
      return arg;
      break;
      default:
      return NULL;
  }
}
static void genstmt(TreeNode *tree)
{
  TreeNode *p1,*p2,*p3;
  ARGrecord ElseLarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
	  OutLarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
	  Earg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
	  startlarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
	  Larg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
	  Rarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
  switch(tree->kind.stmt){
  case IfK:
   p1=tree->child[0];
   p2=tree->child[1];
   p3=tree->child[2];
   ElseLarg=ARGlabel();
   OutLarg=ARGlabel();
   Earg=genexp(p1);
   if(Earg->form==ValueForm)   
    fprintf(code,"%s %d %s%d\n","JUMP0",Earg->atr.value,"L",ElseLarg->atr.label);
   if(Earg->form==AddrForm)
	fprintf(code,"%s %s %s%d\n","JUMP0",Earg->atr.addr->name ,"L",ElseLarg->atr.label);
   if(Earg->form==TddrForm)
	fprintf(code,"%s %s%d %s%d\n","JUMP0","T",Earg->atr.addr->dataoff, "L",ElseLarg->atr.label);
   GenMidCode(p2,code);
   fprintf(code,"%s %s%d\n","JUMP","L",OutLarg->atr.label);
   fprintf(code,"%s%d:\n","L",ElseLarg->atr.label);
   GenMidCode(p3,code);
   fprintf(code,"%s%d:\n","L",OutLarg->atr.label);
   break;
 case RepeatK:
    p1=tree->child[0];
    p2=tree->child[1];
	startlarg=ARGlabel();
    fprintf(code,"%s%d:","L",startlarg->atr.label);
     GenMidCode(p1,code);
    Earg=genexp(p2);
	if(Earg->form==ValueForm)   
	fprintf(code,"%s %d %s%d\n","JUMPN0",Earg->atr.value,"L",startlarg->atr.label);
	if(Earg->form==AddrForm)
	fprintf(code,"%s %s %s%d\n","JUMPN0",Earg->atr.addr->name,"L",startlarg->atr.label);
	if(Earg->form==TddrForm)
	fprintf(code,"%s %s%d %s%d\n","JUMPN0","T",Earg->atr.addr->dataoff,"L",startlarg->atr.label);
    break;
 case  AssignK:
    Larg->atr.addr=(address)malloc(sizeof(struct AddressRec));
	Larg->atr.addr->name=tree->attr.name;
    Rarg=genexp(tree->child[0]);
	if(Rarg->form==ValueForm)   
	fprintf(code,"%s %s %d\n","ASSIG",Larg->atr.addr->name,Rarg->atr.value);
	if(Rarg->form==AddrForm)
	fprintf(code,"%s %s %s\n","ASSIG",Larg->atr.addr->name,Rarg->atr.addr->name );
	if(Rarg->form==TddrForm)
	fprintf(code,"%s %s %s%d\n","ASSIG",Larg->atr.addr->name,"T",Rarg->atr.addr->dataoff);
    break;
 case  ReadK:
    Larg->atr.addr=(address)malloc(sizeof(struct AddressRec));
	Larg->atr.addr->name=tree->attr.name;
    fprintf(code,"%s %s \n","READC",Larg->atr.addr->name);
    break;
  case WriteK:
    Larg=genexp(tree->child[0]);
	if(Larg->form==ValueForm)   
	fprintf(code,"%s %d \n","WRITEC",Larg->atr.value);
	if(Larg->form==AddrForm)
	fprintf(code,"%s %s \n","WRITEC",Larg->atr.addr->name );
	if(Larg->form==TddrForm)
	fprintf(code,"%s %s%d\n","WRITEC","T",Larg->atr.addr->dataoff);
    break;
    default:
      break;
  }
}



  
void GenMidCode( TreeNode *tree,FILE* codefile)
{if(tree!=NULL)
  {switch(tree->nodekind) {
   case StmtK:
      genstmt(tree);
      break;
   case  ExpK:
       genexp(tree);
       break;
   default: 
      break;
     }
   GenMidCode(tree->sibling,code);
  }
}

⌨️ 快捷键说明

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