?? 編譯原理試驗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 + -