奥鹏作业答案-谋学网-专业的奥鹏在线作业答案辅导网【官网】

 找回密码
 会员注册

微信登录,扫一扫

手机号码,快捷登录

VIP会员,3年作业免费下 !奥鹏作业,奥鹏毕业论文检测新手作业下载教程,充值问题没有找到答案,请在此处留言!
2022年5月最新全国统考资料投诉建议,加盟合作!点击这里给我发消息 点击这里给我发消息
奥鹏课程积分软件(2021年最新)
查看: 1566|回复: 0

西交11春《编译原理》复习题

[复制链接]
发表于 2011-7-20 08:42:10 | 显示全部楼层 |阅读模式
谋学网
西交《编译原理》第十一章 目标代码生成 拓展资源
目:逆波兰式生成目标代码
逆波兰式,用于编译器的实现,效率高,但是实现的难度相对于四元式,本人认为要高。

#include<iostream>               /* 基本输入输出流 */
#include<stack>                  /* 运用栈,省去自己再写栈 */
using namespace std;
/***************************************
*                 数据结构             *
*       逆波兰式==> 目标代码           *
***************************************/
/*********************************************
*   目标代码指令:LD,ST,ADD,SUB,MUL,DIV *
*   相应的数值  :1,  2,  3,  4,  5,  6 *
*   数据段开始:设置为a-z;单个寄存器        *
* acc为寄存器标志:为0表示为空,非0,被占用*
*********************************************/
char temp='a'-1;       /* 临时变量a-z   */
stack<char> SEM;       /* 语义栈        */
int s;                 /* 栈指针        */
typedef struct
{
int op;            /* 操作符对应的数值 */
char rt;           /* 单个寄存器       */
char num;          /* 操作数           */
}ObjType;
ObjType OB[40];        /* 目标代码区       */
int o_pt=0;            /* 区指针           */
int acc;               /* 寄存器标志       */
char blexp[40];        /* 逆波兰式区       */

/*************************************
*              代码区                *
*************************************/
/*************************************
*           函数声明                 *
*************************************/
int isop(char);      /* 判断操作符是否是+-/* */
void build(char);    /* 根据操作符生成目标代码函数 */
void B_O();    /* 生成算法 */
char* OpString(int); /* 操作符转化成字符显示 */
void display();   /* 显示目标代码 */

/*************************************
*    判断当前操作符是否是运算符      *
*       如果是返回相应的正数(3-6)    *
*       否则返回零                   *
*************************************/
int isop(char ch)
{
if(ch=='+')
  return 3;
else if(ch=='-')
  return 4;
else if(ch=='*')
  return 5;
else if(ch=='/')
  return 6;
else
  return 0;
}
/*********************************************
*        目标代码生成表生成目标代码         *
*********************************************/
/***************************目标代码生成表****************************************************************
* 操作符W  SEM[s-1]即x1 SEM[s]即x2  acc   OBJ                   *
* +-/*    X1         X2        0     LD R,X1;W R,X2;        *
* +-/*    X1         X2       K!=0   T=NEW T;ST R,T;LD R,X1;W R,X2;*
* +-/*    R           X        s-1   W R,X;       *
* +*      X           R         s    W R,X;       *
* /-      X           R          s   T=NEW T;ST R,T;LD R,X;W R,T; *
*******************************************************************/
void build(char ch)
{
char x1,x2;                   /* 从语义栈中弹出俩个操作数,用于判断与运算 */
x2=SEM.top();                 /* SEM.top 记得后面要加(),否则没有值!!!     */
cout<<x2<<endl;      /* 用于调试用的,看栈是怎样变化的 */
SEM.pop();
x1=SEM.top();
cout<<x1<<endl;
SEM.pop();
if(acc==0)                    /* 如果寄存器没被占用,直接生成运算指令     */
{
  OB[o_pt].op=1;            /* 装载SEM[S-1]即x1 到寄存器R               */
  OB[o_pt].rt='R';
  OB[o_pt].num=x1;
  o_pt++;
  OB[o_pt].op=isop(ch);     /* 生成对应的运算指令                       */
  OB[o_pt].rt='R';
  OB[o_pt].num=x2;
  o_pt++;
}
else if(x1!='R'&&x2!='R'&&acc!=0) /* x1和x2都不是寄存器的值,且寄存器被占用 */
{                              
  temp++;                       /* 申请一个临时变量,在执行代码生成过程中,由操作系统生成,这个是模拟 */
  OB[o_pt].op=2;      /*  将寄存器的值移出到临时变量 */
  OB[o_pt].rt='R';         
  OB[o_pt].num=temp;
  SEM.pop();                    /* 将临时变量压入语义栈    */
  SEM.push(temp);
  o_pt++;
  OB[o_pt].op=1;                /* 装载操作数 */
  OB[o_pt].rt='R';
  OB[o_pt].num=x1;
  o_pt++;
  OB[o_pt].op=isop(ch);         /* 生成运算指令 */
  OB[o_pt].rt='R';
  OB[o_pt].num=x2;
  o_pt++;
}
else if(x1=='R'&&x2!='R'&&acc==(s-1))/* SEM[s-1]即x1为寄存器的值而x2是操作数且acc为s-1,说明寄存器现在的值为x1 */
{
  OB[o_pt].op=isop(ch);            /* 直接生成运算指令,因为此时的寄存器中已经存在一个操作数 */
  OB[o_pt].rt='R';
  OB[o_pt].num=x2;
  o_pt++;
}
else if(x1!='R'&&x2=='R'&&acc==s&&(isop(ch)==3||isop(ch)==5))/* 寄存器的值在SEM[s]即x2,如果操作符为+*  */
{
  OB[o_pt].op=isop(ch);                                    /* 直接生成运算指令 */
  OB[o_pt].rt='R';
  OB[o_pt].num=x1;
  o_pt++;
}
else if(x1!='R'&&x2=='R'&&acc==s&&(isop(ch)==4||isop(ch)==6))/* 如果是- /,则需要调换一下位置 */
{
  temp++;              /* 生成临时变量,用于存储下寄存器值 */
  OB[o_pt].op=2;
  OB[o_pt].rt='R';           /* 不需要压栈,因为马上就要用到 */
  OB[o_pt].num=temp;
  o_pt++;
  OB[o_pt].op=1;            /* 装载x1如寄存器  */
  OB[o_pt].rt='R';
  OB[o_pt].num=x1;
  o_pt++;
  OB[o_pt].op=isop(ch);          /* 利用临时变量生成运算指令 */
  OB[o_pt].rt='R';
  OB[o_pt].num=temp;
  o_pt++;
}
else               /* 出错处理 */
{
  cout<<"不符合目标代码生成条件,出错!"<<endl;
  exit(0);
}
SEM.push('R');  /* 将寄存器'R'压栈,用于下次判断,而不是寄存器的值 */
s--;
return;
}
/******************************
*  生成算法     *
******************************/
void B_O()
{
int i=0;    /* 置初始值s=0,acc=0,i=0 */
char ch;    /* 当前处理字符 */
s=0;     /* s 为栈顶指示 */
acc=0;
while(blexp[i]!='\0')   /* 逆波兰式区还没处理完 */
{
  ch=blexp[i++];  /* 取当前处理字符  */
  if(isalnum(ch))  /* 是操作数,入栈 */
  {
   SEM.push(ch);
   s++;
  }
  else if(isop(ch)) /* 是操作符,生成指令 */
  {
   build(ch);
   acc=s;   /* acc标志到栈顶,因为R入栈了,指示R的位置用,是个技巧 */
  }
  else              /* 字符不符合要求,出错处理 */
  {
   cout<<"逆波兰式内字符有错!"<<endl;
   exit(0);
  }
}
}
/*****************************************
*    将操作指令的数值转换成相应的字符串  *
*****************************************/
char* OpString(int i)
{
switch(i)
{
case 1:
  return "LD";
case 2:
  return "ST";
case 3:
  return "ADD";
case 4:
  return "SUB";
case 5:
  return "MUL";
case 6:
  return "DIV";
default:
  cout<<"操作符有错!"<<endl;
  exit(0);
}
}
/*******************************
*        显示目标代码          *
*******************************/
void display()
{
int i;
cout<<"==============目标代码=========="<<endl;
for(i=0;i<o_pt;i++)
{
  cout<<OpString(OB[i].op)<<"\t"<<OB[i].rt<<","<<OB[i].num<<endl;
  
}
}

int main()
{
cout<<"逆波兰式生成目标代码"<<endl;
cout<<"请输入逆波兰式:"<<endl;
gets(blexp);
B_O();
display();
return 1;
}
奥鹏作业答案,奥鹏在线作业答案
您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

 
 
客服一
客服二
客服三
客服四
点这里给我发消息
点这里给我发消息
谋学网奥鹏同学群2
微信客服扫一扫

QQ|关于我们|联系方式|网站特点|加入VIP|加盟合作|投诉建议|法律申明|Archiver|小黑屋|奥鹏作业答案-谋学网 ( 湘ICP备2021015247号 )

GMT+8, 2025-2-3 06:59 , Processed in 0.076781 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2025 Tencent Cloud.

快速回复 返回顶部 返回列表