二编:看到我实验六的应该都知道我实验五写错了……所以写完实验六来亡羊补牢一下。
防止后来人不知道错哪了,我指一下:
1.实验文件里给的是for语句要包含for语句后的执行语句,我把它割裂出去了,以至于for语句机器代码生成不对(当时真不理解label是干嘛用的,但是实验六之后就理解了)
2.write j这句话(不管是write id 还是write num),我忘记LOAD了,也就是说我输出的是其他数字,不是j的值。
实验六因为这个改了两小时,生气了要。
先看下输出文件的样子。
LOADI
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
ADD
STO 1
POP
BR 5
LABEL7:
LAOD 0
LOAD 1
MULT
STO 0
POP
BR 8
LABEL6:
LOAD 0
OUT
原文:
为什么没有实验四呢,因为实验四第二题不会写……对,老师也不讲,first不会拆,更别说follow了。而且那三周刚好期中考试,忙到飞起,所以……嗯嗯你们懂得
实验五里我们的任务很简单,就是生成机器代码,然后伙计们应该能看见老师给的那几个机器代码模版,我们要做的就是按照那个模版套就完事了,所以实验五很简单。
首先我们看一下最终结果(我不确定……应该长这样吧……那个实验提纲我的理解就是这样了……所以……有错你们改一下吧)
我用的语句是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;","}"};
至于为什么不读文件……我c++学的很差,文件不会读(而且mac是rtf文件,我也很为难嘛)
并且,代码我偷了大懒,因为语句里只有for,所以while我没写,if我也没写,你们需要写可以直接复制for语句的去套模版,其实万变不离其宗,对吧
但是这个代码缺陷也很明显,除了没有考虑很多其他可能以外,我把几种状况全塞ifint()函数中写了,所以ifint()函数会显得很臃肿。另外,ifint()函数中的return 0;就是个断点用的,因为你会发现我直接在int main()中执行了,所以其实我们应该再加一个判错的小函数,将ifint()放在其中执行,有错直接中断,然后int main()放这个小函数。但是我想偷懒啦……
放代码咯
#include <string>
#include <iostream>
#include<vector>
#include<string.h>
#include<fstream>
#define maxnum 100
using namespace std;
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;","}"};
int linelen=10;
char id[maxnum];
int countid=0;
int nowline=1;
int label=0;
int lookup(char goalid){
for(int j=0;j<countid;++j){
if(id[j]==goalid){
return j;
}
}
return -1;
}
ofstream ofile;
int ifint(){
int tempsit=line[nowline].length();
string tempchar="";
for(int i=0;i<tempsit;++i){
if(line[nowline][i]==' '){
i++;
if(tempchar=="int"){
tempchar="";
for(int j=i;j<tempsit;++j){
if(line[nowline][j]==';'){
id[countid]=tempchar[0];
countid++;
label++;
nowline++;
i=j+1;
return 1;
}
tempchar+=line[nowline][j];
}
return 0;
}
else if (tempchar=="read"){
for(int j=i;j<tempsit;++j){
if(line[nowline][j]==';'){
int tempnum=lookup(tempchar[0]);
if(tempnum==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
ofile<<"LOOKUP("<<tempchar[0]<<","<<tempnum<<")"<<endl;
ofile<<"IN"<<endl;
ofile<<"STO"<<" "<<tempnum<<endl;
nowline++;
label++;
i=j+1;
return 1;
}
tempchar[0]=line[nowline][j];
}
return 0;
}
else if (tempchar=="write"){
for(int j=i;j<tempsit;++j){
if(line[nowline][j]==';'){
ofile<<"LOAD "<<lookup(line[nowline][j-1])<<endl;
ofile<<"OUT"<<endl;
nowline++;
label++;
i=j+1;
return 1;
}
tempchar[0]=line[nowline][j];
}
return 0;
}
return 0;
}
else if (line[nowline][i]=='='){
int flag=0;
i++;
int tempnum1=lookup(tempchar[0]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
tempchar="";
for(int j=i;j<tempsit;++j){
if (line[nowline][j]=='*' or line[nowline][j]=='+' or line[nowline][j]==';'){
if(isnumber(tempchar[0])){
ofile<<"LOADI "<<tempchar<<endl;
}
else if(isalpha(tempchar[0])){
int tempnum=lookup(tempchar[0]);
if(tempnum==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
ofile<<"LOAD "<<tempnum<<endl;
}
else{
return 0;
}
if(line[nowline][j]=='*'){
flag=1;
}
else if(line[nowline][j]=='+'){
flag=2;
}
else if(line[nowline][j]==';'){
if(flag==1){
ofile<<"MULT"<<endl;
}
else if(flag==2){
ofile<<"ADD"<<endl;
}
ofile<<"STO "<<tempnum1<<endl;
nowline++;
label++;
return 1;
}
}
else{
tempchar[0]=line[nowline][j];
}
}
return 0;
}
else if (line[nowline][i]=='('){
i++;
if(tempchar=="for"){
for(int j=i;j<tempsit;++j){
if(line[nowline][j]=='='){
tempchar[0]=line[nowline][j-1];
}
else if (line[nowline][j]==';'){
tempchar[1]=line[nowline][j-1];
i=j+1;
break;
}
}
int tempnum1=lookup(tempchar[0]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
if(isnumber(tempchar[1])){
ofile<<"LOADI "<<tempchar[1]<<endl;
}
else{
int tempnum2=lookup(tempchar[1]);
if(tempnum2==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[1]<<endl;
return 0;
}
ofile<<"LOAD "<<tempnum2<<endl;
}
ofile<<"STO "<<tempnum1<<endl;
ofile<<"POP"<<endl;
ofile<<"LABEL"<<label<<":"<<endl;
int flag=0;
for(int j=i;j<tempsit;++j){
if(line[nowline][j]=='<' or line[nowline][j]=='>'){
tempchar[0]=line[nowline][j-1];
if(line[nowline][j]=='<'){
flag=1;
}
else if (line[nowline][j]=='>'){
flag=3;
}
}
else if (line[nowline][j]=='='){
flag++;
}
else if (line[nowline][j]==';'){
tempchar[1]=line[nowline][j-1];
i=j+1;
break;
}
}
tempnum1=lookup(tempchar[0]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
else{
ofile<<"LOAD "<<tempnum1<<endl;
}
if(isnumber(tempchar[1])){
ofile<<"LOADI "<<tempchar[1]<<endl;
}
else{
int tempnum2=lookup(tempchar[1]);
if(tempnum2==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[1]<<endl;
return 0;
}
ofile<<"LOAD "<<tempnum2<<endl;
}
switch(flag){
case 1:
ofile<<"LES"<<endl;
break;
case 2:
ofile<<"LE"<<endl;
break;
case 3:
ofile<<"GT"<<endl;
break;
case 4:
ofile<<"GE"<<endl;
break;
default:
return 0;
break;
}
ofile<<"BRF "<<label+1<<endl;
ofile<<"BR "<<label+2<<endl;
ofile<<"LABEL"<<label+3<<":"<<endl;
for(int j=i;j<tempsit;++j){
if (line[nowline][j]=='='){
flag++;
tempchar[0]=line[nowline][j-1];
}
else if (line[nowline][j]=='+' or line[nowline][j]=='-'){
tempchar[1]=line[nowline][j-1];
if(line[nowline][j]=='+'){
flag=1;
}
else if (line[nowline][j]=='-'){
flag=2;
}
}
else if (line[nowline][j]==')'){
tempchar[2]=line[nowline][j-1];
i=j+1;
break;
}
}
tempnum1=lookup(tempchar[1]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[1]<<endl;
return 0;
}
else{
ofile<<"LOAD "<<tempnum1<<endl;
}
if(isnumber(tempchar[1])){
ofile<<"LOADI "<<tempchar[2]<<endl;
}
switch(flag){
case 1:
ofile<<"ADD"<<endl;
break;
case 2:
ofile<<"SUB"<<endl;
break;
default:
return 0;
break;
}
tempnum1=lookup(tempchar[0]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
else{
ofile<<"STO "<<tempnum1<<endl;
}
ofile<<"POP"<<endl;
ofile<<"BR "<<label<<endl;
ofile<<"LABEL"<<label+2<<":"<<endl;
for(int j=i;j<tempsit;++j){
if (line[nowline][j]=='='){
flag++;
tempchar[0]=line[nowline][j-1];
}
else if (line[nowline][j]=='*' or line[nowline][j]=='/'){
tempchar[1]=line[nowline][j-1];
if(line[nowline][j]=='*'){
flag=1;
}
else if (line[nowline][j]=='/'){
flag=2;
}
}
else if (line[nowline][j]==';'){
tempchar[2]=line[nowline][j-1];
i=j+1;
break;
}
}
tempnum1=lookup(tempchar[1]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[1]<<endl;
return 0;
}
else{
ofile<<"LAOD "<<tempnum1<<endl;
}
if(isnumber(tempchar[2])){
ofile<<"LOADI "<<tempchar[2]<<endl;
}
else{
int tempnum2=lookup(tempchar[2]);
if(tempnum2==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[2]<<endl;
return 0;
}
ofile<<"LOAD "<<tempnum2<<endl;
}
switch(flag){
case 1:
ofile<<"MULT"<<endl;
break;
case 2:
ofile<<"DIV"<<endl;
break;
default:
return 0;
break;
}
tempnum1=lookup(tempchar[0]);
if(tempnum1==-1){
cout<<"第"<<nowline+1<<"行出现未定义变量"<<tempchar[0]<<endl;
return 0;
}
else{
ofile<<"STO "<<tempnum1<<endl;
}
ofile<<"POP"<<endl;
ofile<<"BR "<<label+3<<endl;
ofile<<"LABEL"<<label+1<<":"<<endl;
label=label+3;
nowline++;
return 1;
}
return 0;
}
tempchar+=line[nowline][i];
}
//cout<<tempchar<<endl;
return 0;
}
int main(){
ofile.open("/Users/apple/Desktop/实验汇总/编译原理实验/实验六/test.txt",ios::out);
for(int k=1;k<9;k++){
ifint();
}
}