简单的代码生成程序
简单的代码生成程序
简单的代码生成程序
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
本题思路:
怎么存储元素?存什么元素???
不管是什么语句,第一个元素都要存入存储器!!!
而且只需要把第一个元素存进去即可,第二个无需存储。
最后需要将运算结果覆盖存储器中的元素。
1、我们可以判断元素是否已经在存储器内
2、其次若在存储器内直接进行操作
3、若不在存储器内则需要给元素寻找一个存储器
4、判断存储器是否已经全部使用,若为全部使用,则使用下一个即可,若全部使用则需要找一个最佳的存储器存放元素
5、最佳的存储器为该存储器内的元素不再被使用或者该元素被使用的语句距离当前语句最远。
#include <bits/stdc++.h>
using namespace std;
int n, m;
string s[110];
char R[15];
int cum = 0; //代表用了cum个存储器
int if_inR(char c)
{
for(int i = 0; i < m; i++)
{
if(c == R[i])
{
return i;
}
}
return -1;
}
int get_fristuseX(int i, char c)
{
for(;i < n; i++)
{
//寻找存储器里的变量的最近使用位置
if(s[i][3] == c || s[i][5] == c)
{
return i;
}
}
//存储器里的变量再也没有被使用过
return n;
}
int get_pos(int i)
{
if(cum < m)
return cum++;
//执行下面这段代码的前提是已经没有可以使用的存储器
//所以要找一个可以替换的存储器
int ans = -1, maxid = -1;
for(int j = 0; j < m; j++)
{
//用id来记录存储器R[j]被再次使用的位置
int id = get_fristuseX(i,R[j]);
//maxid 用来寻找可以R[j]被再次使用的最远位置
//或者存储器内存的变量不再被使用
if(id > maxid)
{
maxid = id;
ans = j;
}
}
return ans;
}
void print_oper(char c)
{
if(c == '+')
{
printf("ADD ");
}
else if(c == '-')
{
printf("SUB ");
}
else if(c == '*')
{
printf("MUL ");
}
else if(c == '/')
{
printf("DIV ");
}
}
void print_right(char c)
{
int pos = if_inR(c);
if(pos != -1)
{
printf("R%d\n", pos);
}
else
{
printf("%c\n", c);
}
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++)
{
cin >> s[i];
}
for(int i = 0; i < n; i++)
{
int pos = if_inR(s[i][3]);
if(pos == -1)
{
pos = get_pos(i);
//这里不可以改为pos < n
//这里是看存储器里的内容还用不用
//用则需要返回内存存起来,不用则直接使用
if(get_fristuseX(i,R[pos]) < n)
{
printf("ST R%d, %c\n",pos,R[pos]);
}
printf("LD R%d, %c\n", pos, s[i][3]);
}
R[pos] = s[i][0];
print_oper(s[i][4]);
printf("R%d, ",pos);
print_right(s[i][5]);
}
}