1、内容
本次设计主要实现了词法分析、语法分析、中间代码生成、DAG优化、目标代码生成5部分,词法分析主要是对源程序的字符串进行分解和扫描,区分出关键字、标识符、常数、操作符。词法分析用自动机实现,每读入一个字符,按照词法规则进行识别,并转换成该字符相对于的Token码,最终生成一个完整的Token串。词法分析是整个编译程序的基础;语法分析在词法分析的基础上,根据语法规则,确定整个输入串在语法上是否正确,本次设计采用递归下降子程序分析法;语义分析和中间代码生成是对语法分析所识别的各类语法范畴进行分析其含义,并以四元式的形式产生中间代码;DAG优化主要是对中间代码进行加工变换以便于产生更加高效的目标代码,只要进行常数合并、公共子表达式提取、删除无用代码等;对于系统的输入,主要是通过文件输入到程序中,要把测试代码保存到指定的文件中。运行时显示一个进入界面,通过选择不同的操作数来实现不同的功能,其中1代表词分析、2代表语法分析、3代表中间代码生成、4代表DAG优化、5代表结束程序。
2、实现的功能
1、词法分析
2、语法分析
3、中间代码生成
4、DAG优化
3、测试过程
通过文件读入程序所能识别的文法,包括定义整型变量,变量的赋值以及整型的加减乘除运算
需要文档的,评论区留言!!(回的不及时)
#include
#include
#include
#include
using namespace std;
/*
*********************************
第一部分:词法分析
*********************************
*/
string keywords[8]= {"main","if","else","for","while","int","void","printf"};
vector<string>Total;
int isdigit(char ch)
{
if(ch>='0'&&ch<='9')
return 1;
return 0;
}
int isletter(char ch)
{
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
return 1;
return 0;
}
int isboundary(char ch)
{
if(ch=='('||ch==')'||ch=='{'||ch=='}'||ch==','||ch==';')
return 1;
return 0;
}
int keys(string g)
{
for(int i=0; i<8; i++)
{
if(g==keywords[i])
return 1;
}
return 0;
}
int isoperator(char ch)
{
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='='||ch=='!'||ch=='<'||ch=='>')
return 1;
return 0;
}
void LexicalAnalysis(string s)
{
for(int i=0; i<s.length();)
{
if(isboundary(s[i]))
{
cout<<"(boundary,"<<s[i]<<")"<<endl;
string t="";
t+=s[i];
Total.push_back(t);
i++;
}
else if(isdigit(s[i]))
{
string g="";
while(isdigit(s[i]))
{
g+=s[i++];
}
cout<<"(integer,"<<g<<")"<<endl;
Total.push_back(g);
}
else if(isletter(s[i])||s[i]=='_')
{
string g="";
while(isletter(s[i])||s[i]=='_'||isdigit(s[i]))
{
g+=s[i++];
}
if(keys(g))
{
cout<<"(keyword,"<<g<<")"<<endl;
Total.push_back(g);
}
else
{
cout<<"(identifier,"<<g<<")"<<endl;
Total.push_back(g);
}
}
else if(isoperator(s[i]))
{
if(i+1<s.length()&&s[i+1]=='=')
{
cout<<"(operator,"<<s[i]<<s[i+1]<<")"<<endl;
string t;
t+=s[i];
t+s[i+1];
Total.push_back(t);
i++;
}
else
{
string t="";
t+=s[i];
cout<<"(operator,"<<s[i]<<")"<<endl;
Total.push_back(t);
}
i++;
}
}
}
/*
********************************************
第二部分:语法分析
********************************************
*/
int cnt=1;
void Program();
void Shengmingxulie();
void Shengmingyuju();
void Biaoshifubiao();
void Yujuxulie();
void Yuju();
void Fuzhiyuju();
void Biaodashi();
void Suanshubiaodashi();
void Xiang();
void Yinzi();
void Biaoshifu();
void Zimu();
void Shuzi();
void Mainguanjianzi();
void Intguanjianzi();
void Print();
void Shuchuyuju();
void Program()
{
if(Total[cnt]=="main")
{
cout<<"<程序> --> () { <声明序列> <语句序列>} " <<endl;
cnt++;
Mainguanjianzi();
if(Total[cnt]=="(")
{
cnt++;
if(Total[cnt]==")")
{
cnt++;
if(Total[cnt]=="{")
{
cnt++;
if(Total[cnt]=="int")
{
Shengmingxulie();
Yujuxulie();
if(Total[cnt]=="}")
{
cnt++;
}
else return ;
}
}
else return ;
}
else return ;
}
else return;
}
else
return ;
}
void Shengmingxulie()
{
cout<<"<声明序列> --> <声明语句> <声明序列>"<<endl;
Shengmingyuju();
if(Total[cnt]=="int")
{
Shengmingxulie();
}
else
{
cout<<"<声明序列> --> <空>"<<endl;
}
}
void Yujuxulie()
{
if(Total[cnt]>="a"&&Total[cnt]<="z"&&Total[cnt]!="print")
{
cout<<"<语句序列> --> <赋值语句> <语句序列>"<<endl;
Fuzhiyuju();
Yujuxulie();
}
else if(Total[cnt]=="print")
{
cout<<"<语句序列> --> <输出语句> <语句序列>"<<endl;
Shuchuyuju();
Yujuxulie();
}
else
{
cout<<"<语句序列> --> <空>"<<endl;
}
}
void Shengmingyuju()
{
cout<<"<声明语句> --> <标识符>" <<endl;
Intguanjianzi();
Biaoshifu();
}
void Biaoshifu()
{
cout<<"<标识符> -->"<<Total[cnt++]<<endl;
if(Total[cnt]==";")
cnt++;
else return;
}
void Fuzhiyuju()
{
cout<<"<赋值语句> --> <标识符> = <算数表达式>"<<endl;
Biaoshifu();
if(Total[cnt]=="=")
cnt++;
else return;
Suanshubiaodashi();
if(Total[cnt]==";")
cnt++;
else return ;
}
void Suanshubiaodashi()
{
if(Total[cnt+1]=="+")
cout<<"<算数表达式> --> <项> + <算数表达式>"<<endl;
else if(Total[cnt+1]=="*")
cout<<"<算数表达式> --> <项> * <算术表达式>" <<endl;
else if(Total[cnt+1]=="-")
cout<<"<算数表达式> --> <项> - <算术表达式>"<<endl;
else if(Total[cnt+1]=="/")
cout<<"<算数表达式> --> <项> / <算术表达式>"<<endl;
else
cout<<"<算数表达式> --> <项>"<<endl;
Xiang();
if(Total[cnt]=="+")
{
cnt++;
Suanshubiaodashi();
}
else if(Total[cnt]=="*")
{
cnt++;
Suanshubiaodashi();
}
else if(Total[cnt]=="-")
{
cnt++;
Suanshubiaodashi();
}
else if(Total[cnt]=="/")
{
cnt++;
Suanshubiaodashi();
}
else
return;
}
void Shuchuyuju()
{
cout<<"<输出语句> --> (<标识符>)" <<endl;
Print();
if(Total[cnt]=="(")
{
cnt++;
Biaoshifu();
if(Total[cnt]==")")
{
cnt++;
if(Total[cnt]==";")
cnt++;
}
}
}
void Print()
{
cout<<" -->" <<Total[cnt++]<<endl;
}
void Xiang()
{
cout<<"<项> --> <因子>"<<endl;
Yinzi();
}
void Yinzi()
{
if(Total[cnt]>="0"&&Total[cnt]<="9")
{
cout<<"<因子> --> <数字>"<<endl;
Shuzi();
}
else
{
cout<<"<因子> --> <标识符>"<<endl;
Biaoshifu();
}
}
void Zimu()
{
cout<<"<字母> --> "<<Total[cnt]<<endl;
cnt++;
}
void Shuzi()
{
cout<<"<数字> --> "<<Total[cnt]<<endl;
cnt++;
}
void Mainguanjianzi()
{
cout<<" --> main" <<endl;
}
void Intguanjianzi()
{
cout<<" --> int" <<endl;
cnt++;
}
/*
***************************************
第三部分:语义中间代码生成
*******************************************
*/
int Find(int ind)
{
for(int i=ind; i<Total.size(); i++)
{
if(Total[i]=="+"||Total[i]=="="||Total[i]=="*"||Total[i]=="-"||Total[i]=="/")
return i;
}
return -1;
}
vector<string>q;
int num=0;
void MiddleCode()
{
cout<<endl;
int id=1;
int index=0;
int tt=0;
while(index<Total.size()||index!=-1)
{
index=Find(index+1);
if(index==-1)
break;
if(Total[index]=="="&&Total[index+2]!="+"&&Total[index+2]!="*"&&Total[index+2]!="-"&&Total[index+2]!="/")
{
q.push_back(Total[index-1]);
q.push_back(Total[index+1]);
printf("%d(=,%s,_,%s)\n",id,q[num++].c_str(),q[num++].c_str());
num-=1;
q.pop_back();
q.pop_back();
q.push_back(Total[index-1]);
id++;
}
else if(Total[index]=="+")
{
printf("%d(+,%s,%s,T%d)\n",id++,Total[index-1].c_str(),Total[index+1].c_str(),tt);
printf("%d(=,T%d,_,%s)\n",id++,tt++,Total[index-3].c_str());
}
else if(Total[index]=="*")
{
printf("%d(*,%s,%s,T%d)\n",id++,Total[index-1].c_str(),Total[index+1].c_str(),tt);
printf("%d(=,T%d,_,%s)\n",id++,tt++,Total[index-3].c_str());
}
else if(Total[index]=="-")
{
printf("%d(-,%s,%s,T%d)\n",id++,Total[index-1].c_str(),Total[index+1].c_str(),tt);
printf("%d(=,T%d,_,%s)\n",id++,tt++,Total[index-3].c_str());
}
else if(Total[index]=="/")
{
printf("%d(/,%s,%s,T%d)\n",id++,Total[index-1].c_str(),Total[index+1].c_str(),tt);
printf("%d(=,T%d,_,%s)\n",id++,tt++,Total[index-3].c_str());
}
}
}
/***********************
DAG 建一个2叉树,节点存编号
***********************/
int FIND(int ind)
{
for(int i=ind; i<Total.size(); i++)
{
if((Total[i]=="="&&Total[i+2]=="+")||(Total[i]=="="&&Total[i+2]=="*")||(Total[i]=="="&&Total[i+2]=="-"||(Total[i]=="="&&Total[i+2]=="/")))
return i;
}
return -1;
}
int Cnt=0;
struct Node
{
int left=-1;
int right=-1;
char id;
vector<char>var;
} node[111];
int n;
int find_var(int i,char c)//查找c是否已经存在
{
int num=node[i].var.size();
for(int j=0; j<num; j++)
if(c==node[i].var[j])
return 1;
return 0;
}
int add_node(char c)//添加节点
{
for(int i=Cnt-1; i>=0; i--)
{
if(node[i].id==c||find_var(i,c))//c已存在,不添加。(存在形式为结点处的op或var里的字母
return i;
}
node[Cnt].id=c;//不存在,新建结点添加
return Cnt++;
}
void add_operator(char op,char c,int l,int r)//添加算符
{
for(int i=Cnt-1; i>=0; i--)
{
if(node[i].left==l&&node[i].right==r&&node[i].id==op)//重复的操作,直接插入到var中
{
node[i].var.push_back(c);
return ;
}
}
node[Cnt].id=op;//不重复的操作,新建一个结点,连接左右子树
node[Cnt].left=l;
node[Cnt].right=r;
node[Cnt].var.push_back(c);
Cnt++;
}
int flag[111];
void dfs(int i)//遍历算术表达式
{
if(node[i].left!=-1)//并非完全的树结构,DAG若左子树存在则右子树一定存在
{
flag[i]=1;
dfs(node[i].left);
dfs(node[i].right);
}
}
char a[111][11];
char ans[111][11];
string getMess(int ind)
{
string Mess="";
if(ind!=-1)
{
Mess+=Total[ind-1];
Mess+=Total[ind];
Mess+=Total[ind+1];
Mess+=Total[ind+2];
Mess+=Total[ind+3];
}
return Mess;
}
int Shizisum=0;
vector<string> ResultDag;
void DAG()
{
int ind=0;
cout<<"未优化前:"<<endl;
vector<char>temp;
while(ind!=-1)
{
ind=FIND(ind+1);
if(ind==-1)
break;
char k[10];
string Temp=getMess(ind); //把这个式子赋值给temp
strcpy(k,Temp.c_str());
cout<<k<<endl;
int l=add_node(k[2]);
int r=add_node(k[4]);
add_operator(k[3],k[0],l,r);
temp.push_back(k[0]);
}
for(int i=0; i<Cnt; i++)
{
if(node[i].left!=-1)//连接左右“子树”,若有子树,则此结点的id必为op
{
ans[i][0]=node[i].var[0];
ans[i][1]='=';
Node ll=node[node[i].left];
Node rr=node[node[i].right];
ans[i][2]=ll.var.size()>0?ll.var[0]:ll.id;//仅优化二元运算
ans[i][3]=node[i].id;
ans[i][4]=rr.var.size()>0?rr.var[0]:rr.id;
}
}
for(int j=0; j<temp.size(); j++)
{
for(int i=Cnt-1; i>=0; i--)
{
if(ans[i][0]==temp[j])
{
dfs(i);
break;
}
}
}
cout<<endl;
cout<<"优化后:"<<endl;
for(int i=0; i<Cnt; i++)
{
if(flag[i])
{
puts(ans[i]);
ResultDag.push_back(ans[i]);
}
}
}
void setWindowStyle()//9e、06、8f
{
system("title 简单编译器");
system("color 07");
}
void show()
{
cout<<"******************************************************************"<<endl;
cout<<"| |"<<endl;
cout<<"| 简单编系统 |"<<endl;
cout<<"| |"<<endl;
cout<<"| 操作一:词法分析 |"<<endl;
cout<<"| 操作二:语法分析 |"<<endl;
cout<<"| 操作三:语义分析 |"<<endl;
cout<<"| 操作四:DAG优化 |"<<endl;
cout<<"| 操作五:退出 |"<<endl;
cout<<"******************************************************************"<<endl;
// cout<<"\t\t************************************************\t\t\n";
// cout<<"\t\t*****************简单编译器**********************\t\t\n";
// cout<<"\t\t************************************************\t\t\n";
printf("请按任意键回车进入该系统\n");
getchar();
fflush(stdin);
//system("cls");
}
int main()
{
setWindowStyle();
show();
ifstream myfile("test.txt");
string s;
while(1){
cout<<"请输入操作";
int x;
cin>>x;
switch(x){
case 1:
while(myfile>>s)
LexicalAnalysis(s);
show();
break;
case 2:
Program();
if(cnt==Total.size())
{
cout<<"文法正确"<<endl;
show();
}
else
{
cout<<"文法错误"<<endl;
return 0;
}
break;
case 3:
MiddleCode();
show();
break;
case 4:
DAG();
break;
case 5:
return 0;
}
}
}