简单的代码生成程序
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
通过三地址代码序列生成计算机的目标代码,在生成算法中,对寄存器的使用顺序为:寄存器中存有 > 空寄存器 > 内存中存有 > 以后不再使用 > 最远距离使用
Input
单组输入,给定输出的三地址代码的个数和寄存器的个数.所有的变量为大写字母,寄存器的数量不超过9
Output
参照示例格式输出,不需要将最后的寄存器中的值写回内存
不再使用变量不用写回内存
Sample Input
4 2
T:=A-B
U:=A-C
V:=T+U
W:=V+U
Sample Output
LD R0, A
SUB R0, B
LD R1, A
SUB R1, C
ADD R0, R1
ADD R0, R1
Hint
Source
#include<bits/stdc++.h>
using namespace std;
int num;//寄存器使用的数量
int n , m;
char R[110];//寄存器
string s[110];//表达式
void PrintOperation(char c)
{
if(c=='-')
cout << "SUB ";
if(c=='+')
cout << "ADD ";
if(c=='*')
cout << "MUL ";
if(c=='/')
cout << "DIV ";
}
int Judge(char c)
{//判断变量是否在寄存器中
for(int i = 0;i<m;i++)
if(R[i]==c) return i;
return -1;
}
int RecentUse(int pos , char c)
{//从当前表达式向后判断,是否有变量早已存在寄存器中
for(int i = pos ;i< n ;i++)
if(s[i][3]==c || s[i][5]==c)return i;
return n;
}
int Find(int pos)
{
//寄存器有空余
if(num < m) return num++;
//寄存器已满
int ii = -1, jj = -1;
//判断这些寄存器中哪些存的变量是最远才使用的
for(int i = 0 ; i<m ;i++)
{
int k = RecentUse(pos, R[i]);
if(k>jj) jj = k, ii = i;
}
return ii;
}
void PrintSecond(char c)
{
int pos = Judge(c);
if(pos != -1)
printf("R%d\n",pos);
else
printf("%c\n",c);
}
int main()
{
memset(R,0,sizeof(R));
num = 0;
int pos;//游标
cin >> n >> m;
getchar();
for(int i =0 ;i<n;i++)
cin >> s[i];
for(int i = 0;i<n;i++)
{
pos = Judge(s[i][3]);
if(pos==-1)
{//变量1不在寄存器中
pos = Find(i);
//如果找到的位置,寄存器已存入变量,且后面的表达式中可能用到这个变量
if(R[pos] && RecentUse(i,R[pos]) < n )
printf("ST R%d, %c\n",pos,R[pos]);//存入内存
printf("LD R%d, %c\n",pos,s[i][3]);
}
//输出操作符
PrintOperation(s[i][4]);
printf("R%d, ",pos);
PrintSecond(s[i][5]);
R[pos]=s[i][0];
}
return 0;
}