我是不是越来越快了!!嘿嘿
这一次写的时候发现之前上传的实验五有大bug,我先手动把文件改对了,实验五我要大改hh,之前写的时候只顾着看说输出了就不管了,真没想到这次给自己挖了个大坑,sadge
这次我们的工作是模拟栈的工作机制。那么先看输出样式。
我们需要按照机器的思路模拟每一个变量进栈出栈以及数值存储的过程。
首先需要两个数组(做成栈也可以,这次我用数组了),一个存储现在在栈中的数字,一个存储变量及其对应的数值。
接下来是解释实验五生成的文件中每一行机器指令。
我单纯说几个我踩坑的。
LOAD num: 将编号为num的变量的值入栈。注意是值!!!!
BRF:记得将栈顶指针向前移一位
没了。很简单。
这次的文件还是老规矩,化成数组就是这样:(为什么再放了一遍,因为实验五我写错了呃呃)
string line[maxnum]={"{","int j;", "j=1;","int i;","int n;","read n;","for(i=1;i<=n;i=i+1)j=j*i;","write j;","}"};
#include<iostream>
#include<string>
#include<fstream>
#include<stack>
#define maxnum 100
using namespace std;
string plan[maxnum];
int planlen;
int id[maxnum];
int num[maxnum];
int stacknum=0;
int findsentence(char n){
for(int k=0;k<planlen;++k){
string tempchar1="";
int selen1=plan[k].length();
for(int m=0;m<=selen1;++m){
if(tempchar1=="LABEL"){
if(plan[k][m]==n){
return k;
}
break;
}
tempchar1+=plan[k][m];
}
}
return -1;
}
int instack(){
for(int i=0;i<planlen;++i){
int selen=plan[i].length();
string tempchar="";
for(int j=0;j<=selen;++j){
if(plan[i][j]==' '){
if(tempchar=="BR"){
i=findsentence(plan[i][j+1]);
break;
}
else if(tempchar=="BRF"){
if(id[stacknum-1]==0){
i=findsentence(plan[i][j+1]);
}
stacknum--;
break;
}
else if (tempchar=="LOAD"){
id[stacknum]=num[int(plan[i][j+1])-48];
stacknum++;
break;
}
else if (tempchar=="LOADI"){
id[stacknum]=int(plan[i][j+1])-48;
stacknum++;
break;
}
else if (tempchar=="STO"){
num[int(plan[i][j+1])-48]=id[stacknum-1];
cout<<"变量编号为"<<int(plan[i][j+1])-48<<" 值为"<<id[stacknum-1]<<endl;
break;
}
}
else if (j==selen){
if(tempchar=="ADD"){
id[stacknum-2]=id[stacknum-2]+id[stacknum-1];
stacknum--;
break;
}
else if(tempchar=="SUB"){
id[stacknum-2]=id[stacknum-2]-id[stacknum-1];
stacknum--;
break;
}
else if(tempchar=="MULT"){
id[stacknum-2]=id[stacknum-2]*id[stacknum-1];
stacknum--;
break;
}
else if(tempchar=="DIV"){
id[stacknum-2]=id[stacknum-2]/id[stacknum-1];
stacknum--;
break;
}
else if (tempchar=="EQ"){
id[stacknum-2]=(id[stacknum-2]==id[stacknum-1]);
stacknum--;
break;
}
else if(tempchar=="NOTEQ"){
id[stacknum-2]=(id[stacknum-2]!=id[stacknum-1]);
stacknum--;
break;
}
else if(tempchar=="GT"){
id[stacknum-2]=(id[stacknum-2]>id[stacknum-1]);
stacknum--;
break;
}
else if(tempchar=="LES"){
id[stacknum-2]=(id[stacknum-2]<id[stacknum-1]);
stacknum--;
break;
}
else if(tempchar=="GE"){
id[stacknum-2]=(id[stacknum-2]>=id[stacknum-1]);
stacknum--;
break;
}
else if(tempchar=="LE"){
id[stacknum-2]=(id[stacknum-2]<=id[stacknum-1]);
stacknum--;
break;
}
else if (tempchar=="IN"){
cout<<"请输入数据:";
int tempnum;
cin>>tempnum;
id[stacknum]=tempnum;
stacknum++;
break;
}
else if (tempchar=="OUT"){
cout<<"输出数据:";
cout<<id[stacknum-1]<<endl;
stacknum--;
break;
}
else if(tempchar=="POP"){
stacknum--;
break;
}
else if (tempchar=="STOP"){
return 1;
}
}
tempchar+=plan[i][j];
}
}
return 0;
}
int main()
{
ifstream fp;
fp.open("/Users/apple/Desktop/实验汇总/编译原理实验/实验六/test.txt", ios::in);
while(!fp.eof()){
string str;
getline(fp, str);
plan[planlen]=str;
planlen++;
}
instack();
return 1;
}
另外给你们看一下修改过之后的机器翻译代码文件。
LOADI 1
STO 0
LOOKUP(n,2)
IN
STO 2
LOADI 1
STO 1
POP
LABEL5:
LOAD 1
LOAD 2
LE
BRF 6
BR 7
LABEL8:
LOAD 1
LOADI 1
ADD
STO 1
POP
BR 5
LABEL7:
LOAD 0
LOAD 1
MULT
STO 0
POP
BR 8
LABEL6:
LOAD 0
OUT
STOP