📄 编译原理试验2.cpp
字号:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct store
{
int type;//标识符类型,0表示整型,1表示布尔型,2表示字符型
int attribution;//36,表示标识符;37表示字符常量,38表示整数
int define;//“0”值时表示没有被定义,“1”值时表示有定义
char content[20];//记录标识符,字符常量和整数及其个数
};
store record[30];
static int record1=1;//记录record数组第一维的数值,即标识符等的个数
struct bexitnode
{
int truesum;//真出口个数
int trueexit[8];//存未知真出口的入口码
int falsesum;//假出口个数
int falseexit[8];//存未知假出口的入口码
int entry;//入口四元式码
int allsum;//四元式总个数
};//布尔表达式中使用
bexitnode bexit[15];
static int pbexit=0;
struct bnode{
char first[20];
char fu[4];
char second[20];
};//布尔表达式中使用
struct node//输出节点
{
string output1;
string output2;
string output3;
string output4;
int Tnum2,Tnum3,Tnum4;
};
node output[60];
static int outputrec=0;
static int Trec=1;//记录T中间变量的个数
struct sentence_node
{
char act;//s代表赋值,i代表if语句,t代表then语句,l代表else语句,w代表while语句,
//r代表repeat语句,u表示until语句,b代表begin语句
int truesum;//真出口个数
int trueexit[5];//存未知真出口的入口码
int falsesum;//假出口个数
int falseexit[5];//存未知假出口的入口码
int entry;//入口四元式码
int row;
int then;
};
sentence_node sentence[20];
int psentence=0;
int sentencerec=0;
void cifaline(char s[80],char* table[35],int & row);//处理一行程序
bool cifafenxi(const char *filename);//词法分析函数
int numberexpression(char * a);//算术表达式是否合法判断
string single;//记录单个变量的表达式情况
int boolexpression(char * str);//布尔表达式是否合法判断
void fguiyue(int & b,int &c,int & pbexit,bexitnode bexit[],bnode bexp[]);//布尔表达式中归约f函数
void gguiyue(int& a,int &c,int & pbexit,bexitnode bexit[],string bsfu[]);//布尔表达式中归约g函数
int chartoint(char a);//从字符转换成为数字
int chattoint2(char a);//从字符转换成为数字
void outputerror(int type,char* str,char* word);//错误提示
int error;
char line[80];//存储文件的一行
static int row=1;//读入文件的第几行
static int position=0;//行的位置
int searchchar(ifstream & tow);//跳过空格和空行寻找字符
int programbegin(ifstream & tow);//编译程序开头
int var(ifstream & tow);//编译变量定义
int begin_end(ifstream & tow);//复合语句函数
int setvalue(ifstream & tow,char temp[],int sen[]);//赋值函数
void main()
{
cout<<" 编译原理实验二\n";
cout<<"\n 姓名:林桂川 班级:计算机04级1班 学号:200433099345\n\n";
const char* filename;
string file;
cout<<"input filename:";
cin>>file;
file+=".txt";
filename=file.data();
if (cifafenxi(filename))//词法分析
{
ifstream tow(filename,ios::in);
if(programbegin(tow)==0)return;
if(var(tow)==0)return;
if(begin_end(tow)==0) return;
tow.close();
for(int j=0;j<outputrec;j++)
{
cout<<j<<"("<<output[j].output1<<",";
if(output[j].output2.compare("T")==0)cout<<"T"<<output[j].Tnum2<<",";
else cout<<output[j].output2<<",";
if(output[j].output3.compare("T")==0)cout<<"T"<<output[j].Tnum3<<",";
else cout<<output[j].output3<<",";
if(output[j].output4.compare("T")==0)cout<<"T"<<output[j].Tnum4<<")";
else if(output[j].output4.compare("j")==0)cout<<output[j].Tnum4<<")";
else cout<<output[j].output4<<")";
cout<<endl;
}
}
}
void outputerror(int type,char* str,char* word)
{
error++;
switch(type)
{
case 1:
cout<<"ERROR "<<error<<"(line "<<row<<"): 缺少关键字说明"<<word<<endl;
break;
case 2:
if (str=="lack_sym")
cout<<"ERROR "<<error<<"(line"<<row<<"): 缺少标点符号 "<<word<<endl;
else
if (str=="false")
cout<<"ERROR "<<error<<"(line "<<row<<"): 非法标志符 "<<endl;
else
if(str=="keyword")
cout<<"ERROR "<<error<<"(line "<<row<<"): 标志符声明不能为关键字 "<<endl;
else
if (str=="lack")
cout<<"ERROR "<<error<<"(line "<<row<<"): 缺少标志符"<<endl;
else
if (str=="error")
cout<<"ERROR "<<error<<"(line "<<row<<"): 变量声明有误"<<endl;
else
if(str=="no_sym")
cout<<"ERROR "<<error<<"(line "<<row<<"): "
<<"非法符号"<<endl;
else
cout<<"ERROR "<<error<<"(line "<<row<<"): "
<<"未声明变量"<<endl;
break;
case 3:
cout<<"ERROR "<<error<<"(line "<<row<<"): 字符常数缺右边的单引号'"<<endl;
break;
case 4:
cout<<"ERROR "<<error<<"(line "<<row<<"): 注释部分缺右边的界符*/"<<endl;
break;
case 5:
cout<<"ERROR "<<error<<"(line "<<row<<"): 此simple语言不提供字符型和布尔型的赋值,请修改"<<endl;
case 6:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<str<<"缺少"<<word<<"的匹配 "<<endl;
break;
case 7:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<word<<"说明后面缺少标志符 "<<endl;
break;
case 8:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<str<<" "<<word<<" 在文中未预料出现 "<<endl;
break;
case 9:
cout<<"ERROR "<<error<<"(line "<<row<<"): 未预见文件结尾 "<<endl;
break;
case 10:
cout<<"ERROR "<<error<<"(line "<<row<<"): 赋值语句错误"<<endl;
break;
case 11:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<" 句子语法构造出错 "<<word<<endl;
break;
case 12:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<"类型不匹配 "<<endl;
break;
case 13:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<"程序已结束,"<<word<<"以下为非法语句"<<endl;
break;
case 14:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<"表达式 "<<word<<" 出错"<<endl;
break;
case 15:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<"布尔表达式 "<<word<<" 中出现非布尔型变量"<<endl;
break;
case 16:
cout<<"ERROR "<<error<<"(line "<<row<<"): "<<"缺少逻辑表达式"<<endl;
break;
}
}
int searchchar(ifstream & tow)//跳跃空格函数
{
for(;line[position]==' '||line[position]=='\0';)
{
for(;line[position]==' ';position++);
if(line[position]=='\0')
{
if(tow.eof())
{
if(sentencerec!=0)
{
outputerror(9,"","");
return 0;
}
else return 1;
}
tow.getline (line,80);
position=0;
row++;
}
}
return 2;
}
int programbegin(ifstream & tow)
{
tow.getline(line,80);
searchchar(tow);
char temp[20];
int i;
for(i=0;line[position]!=' '&&line[position]!='\0';i++,position++)temp[i]=line[position];
temp[i]='\0';
if(strcmp(temp,"program")!=0)
{
outputerror(1,"","program");
return 0;
}
output[outputrec].output1="program";//
searchchar(tow);
for(i=0;line[position]!=' '&&line[position]!=';'&&line[position]!='\0';i++,position++)
temp[i]=line[position];
temp[i]='\0';
for(i=1;strcmp(temp,record[i].content)!=0&&i<record1;i++);
if(i==record1)
{
outputerror(2,"lack","");
return 0;
}
output[outputrec].output2.assign(temp);
output[outputrec].output3="-";
output[outputrec].output4="-";
outputrec++;
searchchar(tow);
if(line[position]!=';')
{
outputerror(2,"lack_sym",";");
return 0;
}
position++;
return 1;
}
int var (ifstream & tow)
{
searchchar(tow);
char temp[20];
int i,j;
for(i=0;line[position]!=' '&&line[position]!='\0'&&line[position]!=','&&line[position]!=':';i++,position++)
temp[i]=line[position];
temp[i]='\0';
if(strcmp(temp,"var")==0)
{
string bsfu[8];
int bsfurec=0;
for(;;)
{
searchchar(tow);
if(!(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122))
{
outputerror(2,"error","");
return 0;
}
for(i=0;(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122)||
(line[position]>=48&&line[position]<=57);i++,position++)
temp[i]=line[position];
temp[i]='\0';
if(strcmp(temp,"begin")==0) return 1;
else
{
for(j=1;strcmp(temp,record[j].content)!=0&&j<record1;j++);
if(j==record1)//标识符是关键字
{
outputerror(2,"keyword","");
return 0;
}
else if(record[j].define==1)
{
outputerror(11,"","");
return 0;
}
}
bsfu[bsfurec].assign(temp);
bsfurec++;
searchchar(tow);
if(line[position]!=','&&line[position]!=':'&&line[position+1]!='=')
{
outputerror(2,"error","");
return 0;
}
if(line[position]==',')
{
position++;
continue;
}
else
{
position++;
searchchar(tow);
if(!(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122))
{
outputerror(2,"error","");
return 0;
}
for(i=0;(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122)||
(line[position]>=48&&line[position]<=57);i++,position++)
temp[i]=line[position];
temp[i]='\0';
if(strcmp(temp,"integer")==0)
{
for(i=0;i<bsfurec;i++)
{
for(j=1;bsfu[i].compare(record[j].content)!=0;j++);
record[j].define=1;
record[j].type=0;
}
bsfurec=0;
}
else if(strcmp(temp,"bool")==0)
{
for(i=0;i<bsfurec;i++)
{
for(j=1;bsfu[i].compare(record[j].content)!=0&&j<record1;j++);
if(j==record1)//标识符是关键字
{
outputerror(2,"keyword","");
return 0;
}
record[j].define=1;
record[j].type=1;
}
bsfurec=0;
}
else if(strcmp(temp,"char")==0)
{
for(i=0;i<bsfurec;i++)
{
for(j=1;bsfu[i].compare(record[j].content)!=0&&j<record1;j++);
if(j==record1)//标识符是关键字
{
outputerror(2,"keyword","");
return 0;
}
record[j].define=1;
record[j].type=2;
}
bsfurec=0;
}
else
{
outputerror(2,"error","");
return 0;
}
searchchar(tow);
if(line[position]!=';')
{
outputerror(2,"lack_sym",";");
return 0;
}
position++;
}
}//for
}//strcmp(temp,"var")==0
else if(strcmp(temp,"begin")==0) return 1;
else
{
outputerror(1,"","var");
return 0;
}
}
int begin_end(ifstream & tow)
{
int sen[20];
sentence[psentence].act='b';
sentence[psentence].entry=outputrec;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
char temp[20];
char str[30];
int i;
for(;;)
{
searchchar(tow);
if(!(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122))
{
outputerror(11,"","");
return 0;
}
for(i=0;(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122)||
(line[position]>=48&&line[position]<=57);i++,position++)
temp[i]=line[position];
temp[i]='\0';
if(strcmp(temp,"if")==0)
{
searchchar(tow);
for(i=0;!(line[position+1]=='t'&&line[position+2]=='h'&&line[position+3]=='e'&&line[position+4]=='n')
&&line[position]!='\0';i++,position++)str[i]=line[position];
str[i]='\0';
if(boolexpression(str)==0)return 0;
sentence[psentence].act='i';
sentence[psentence].entry=bexit[0].entry;
sentence[psentence].falsesum=bexit[0].falsesum;
sentence[psentence].truesum=bexit[0].truesum;
for(i=0;i<bexit[0].falsesum;i++)sentence[psentence].falseexit[i]=bexit[0].falseexit[i];
for(i=0;i<bexit[0].truesum;i++)sentence[psentence].trueexit[i]=bexit[0].trueexit[i];
sentence[psentence].row=row;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
}
else
if(strcmp(temp,"then")==0)
{
sentence[psentence].act='t';
sentence[psentence].entry=outputrec;
sentence[psentence].row=row;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
}
else
if(strcmp(temp,"else")==0)
{
sentence[psentence].act='l';
sentence[psentence].entry=outputrec;
sentence[psentence].row=row;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
}
else
if(strcmp(temp,"while")==0)
{
searchchar(tow);
for(i=0;!(line[position]=='d'&&line[position+1]=='o')
&&line[position]!='\0';i++,position++)str[i]=line[position];
str[i]='\0';
if(boolexpression(str)==0)return 0;
sentence[psentence].act='w';
sentence[psentence].entry=bexit[0].entry;
sentence[psentence].falsesum=bexit[0].falsesum;
sentence[psentence].truesum=bexit[0].truesum;
for(i=0;i<bexit[0].falsesum;i++)sentence[psentence].falseexit[i]=bexit[0].falseexit[i];
for(i=0;i<bexit[0].truesum;i++)sentence[psentence].trueexit[i]=bexit[0].trueexit[i];
sentence[psentence].row=row;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
searchchar(tow);
if(line[position]=='d'&&line[position+1]=='o')
{
sentence[psentence].act='d';
sentence[psentence].entry=outputrec;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
position+=2;
}
else
{
outputerror(6,"while","do");
return 0;
}
}
else
if(strcmp(temp,"repeat")==0)
{
sentence[psentence].act='r';
sentence[psentence].entry=outputrec;
sentence[psentence].row=row;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
}
else
if(strcmp(temp,"until")==0)
{
searchchar(tow);
for(i=0;!(line[position+1]=='d'&&line[position+2]=='o')//
&&line[position]!='\0';i++,position++)str[i]=line[position];
str[i]='\0';
if(boolexpression(str)==0)return 0;
if(sen[sentencerec-1]==100&&sentence[sen[sentencerec-2]].act=='r')
{
for(i=0;i<bexit[0].falsesum;i++)
output[bexit[0].falseexit[i]].Tnum4=sentence[sen[sentencerec-2]].entry;
for(i=0;i<bexit[0].truesum;i++)
output[bexit[0].trueexit[i]].Tnum4=outputrec;
sen[sentencerec-2]=100;
sentencerec--;
}
else
{
outputerror(6,"repeat","until");
return 0;
}
}
else
if(strcmp(temp,"begin")==0)
{
sentence[psentence].act='b';
sentence[psentence].entry=outputrec;
sentence[psentence].row=row;
sen[sentencerec]=psentence;
sentencerec++;
psentence++;
}
else
if(strcmp(temp,"end")==0)
{
if(sen[sentencerec-1]!=100)
{
if(sentence[sen[sentencerec-1]].act=='i')
{
outputerror(6,"","if");
return 0;
}
else if(sentence[sen[sentencerec-1]].act=='w')
{
outputerror(6,"","while");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -