📄 词法分析器.cpp
字号:
#include<iostream.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE1 14 //定义保留字数目
#define MAXSIZE2 20
char end; //结尾判断标志
char line[100]; // 存储每次从源文件中读取的一行
char spelling[MAXSIZE2]; //记录正在读取字符的缓冲区
char *pline; //行缓冲区指针
char ch='\0'; //ch的当前值为开始读文件的条件
int linenum=0; //记录源文件行数
int misnum=0; //记录错误数
int slength=0; //标识符表记录数
int nlength=0; //常数表记录数
int rlength=0; //分析结果缓冲区记录数
ifstream openFile; //定义打开文件类
ofstream saveFile; //定义结果文件类
char *key[MAXSIZE1]={"int","char","float","void","const","for","if","else","then","which","switch","break","begin","end"};
typedef struct //标识符表
{
char name[MAXSIZE2];
int type;
char *address;
}signword;
signword sign[100];
typedef struct //常数表
{
char name[MAXSIZE2];
int value;
}numword;
numword number[100];
typedef struct //词法分析结果缓冲区结构
{
char sig[MAXSIZE2];
char val[MAXSIZE2];
}buffer;
buffer buf[1000];
/*************初始化函数***************/
void init()
{
char c[2]="-";
for(int i=0;i<1000;i++)
{
strcpy(buf[i].val,c);
}
}
/*************从文件中读出一行放入缓冲区line[]中********************************/
void readline()
{
char ch1;
pline=line; //将指针指向缓冲区的起始位置
openFile.get(ch1);
end=ch1;
while(ch1!='\n'&&end!=EOF)
{
*pline=ch1;
pline++;
openFile.get(ch1);
}
*pline='\0';
pline=line;
}
/***********************从缓冲区中读一个字符*********************************/
void readch()
{
if(ch=='\0')
{
readline();
linenum++;
}
ch=*pline;
pline++;
}
/********************保留字查找函数******************************/
int keyfind(char arr[])
{
int s=0,i=0;
while((s==0)&&(i<MAXSIZE1))
{
if(!strcmp(arr,key[i])) s=1;
i++;
}
if(s==1) return (i-1);
return -1;
}
/******************识别保留字和标识符函数**********************************/
void isalpha()
{
int k=0,s=0,i=0;
do
{
spelling[k]=ch;
k++;
readch();
}while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9')));
pline--; //缓冲区指针减退一步
spelling[k]='\0';
int n=keyfind(spelling);
if(n!=-1) //关键字匹配
{
strcpy(buf[rlength].sig,spelling);
}
else
{
buf[rlength].sig[0]='i';
buf[rlength].sig[1]='d';
buf[rlength].sig[2]='\0';
while((s==0)&&(i<=slength))
{
if(!strcmp(sign[i].name,spelling)) s=1;
i++;
}
if(s==0)
{
strcpy(sign[slength].name,spelling);
itoa(slength,buf[rlength].val,10);
slength++;
}
else
itoa(--i,buf[rlength].val,10);
}
rlength++;
for(k=0;k<MAXSIZE2;k++) spelling[k]=' ';
}
/*****************************识别数字函数*****************************/
void isnumber()
{
int s=0,i=0,k=0;
do
{
spelling[k]=ch;
k++;
readch();
}while((ch>='0')&&(ch<='9'));
if(ch=='.')
{
char c=ch;
readch();
if(ch<='0'||ch>='9')
{
cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行.字符错误"<<endl;
misnum++;
}
else
{
spelling[k]=c;
k++;
while((ch>='0')&&(ch<='9'))
{
spelling[k]=ch;
k++;
readch();
}
}
}
pline--;
spelling[k]='\0';
buf[rlength].sig[0]='n';
buf[rlength].sig[1]='u';
buf[rlength].sig[2]='m';
buf[rlength].sig[3]='\0';
while((s==0)&&(i<=nlength))
{
if(!strcmp(number[i].name,spelling)) s=1;
i++;
}
if(s==0)
{
strcpy(number[nlength].name,spelling);
itoa(nlength,buf[rlength].val,10);
nlength++;
}
else
itoa(--i,buf[rlength].val,10);
rlength++;
for(k=0;k<MAXSIZE2;k++) spelling[k]=' ';
}
/***************************处理除号和注释函数**************************/
void isanotation()
{
int n=linenum;
readch();
switch(ch)
{
case '=':
buf[rlength].sig[0]='/';
buf[rlength].sig[1]='=';
buf[rlength].sig[2]='\0';
rlength++;
break;
case '*':
while(end!=EOF)
{
do
{
readch();
}while(ch!='*'&&end!=EOF);
if(end!=EOF)
{
readch();
if(ch=='/') break;
}
}
if(end==EOF)
{
cout<<"错误"<<misnum<<":"<<"第"<<n<<"行注释符没有结尾"<<endl;
misnum++;
}
break;
default:
buf[rlength].sig[0]='/';
buf[rlength].sig[1]='\0';
rlength++;
pline--;
break;
}
}
/*****************识别函数*****************/
void scanner()
{
while(end!=EOF)
{
switch(ch)
{
case ' ': break;
case '\0': break;
case '_':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
case 'V': case 'W': case 'X': case 'Y': case 'Z':
isalpha();
break;
case '0': case '1': case '2': case '3': case '4': case '5': case '6':
case '7': case '8': case '9':
isnumber();
break;
case '/':
isanotation();
break;
case ';':
buf[rlength].sig[0]=';';
buf[rlength].sig[1]='\0';
rlength++;
break;
case '[':
buf[rlength].sig[0]='[';
buf[rlength].sig[1]='\0';
rlength++;
break;
case ']':
buf[rlength].sig[0]=']';
buf[rlength].sig[1]='\0';
rlength++;
break;
case '(':
buf[rlength].sig[0]='(';
buf[rlength].sig[1]='\0';
rlength++;
break;
case ')':
buf[rlength].sig[0]=')';
buf[rlength].sig[1]='\0';
rlength++;
break;
case '+':
readch();
if(ch=='=')
{
buf[rlength].sig[0]='+';
buf[rlength].sig[1]='=';
buf[rlength].sig[2]='\0';
}
else
{
buf[rlength].sig[0]='+';
buf[rlength].sig[1]='\0';
pline--;
}
rlength++;
break;
case '-':
readch();
if(ch=='=')
{
buf[rlength].sig[0]='-';
buf[rlength].sig[1]='=';
buf[rlength].sig[2]='\0';
}
else
{
buf[rlength].sig[0]='-';
buf[rlength].sig[1]='\0';
pline--;
}
rlength++;
break;
case '*':
readch();
if(ch=='=')
{
buf[rlength].sig[0]='*';
buf[rlength].sig[1]='=';
buf[rlength].sig[2]='\0';
}
else
{
buf[rlength].sig[0]='*';
buf[rlength].sig[1]='\0';
pline--;
}
rlength++;
break;
case '!':
readch();
if(ch=='=')
{
buf[rlength].sig[0]='r';
buf[rlength].sig[1]='l';
buf[rlength].sig[2]='o';
buf[rlength].sig[3]='p';
buf[rlength].sig[4]='\0';
buf[rlength].val[0]='!';
buf[rlength].val[1]='=';
buf[rlength].val[2]='\0';
rlength++;
}
else
{
buf[rlength].sig[0]='n';
buf[rlength].sig[1]='o';
buf[rlength].sig[2]='t';
buf[rlength].sig[3]='\0';
rlength++;
pline--;
}
break;
case '<':
readch();
buf[rlength].sig[0]='r';
buf[rlength].sig[1]='l';
buf[rlength].sig[2]='o';
buf[rlength].sig[3]='p';
buf[rlength].sig[4]='\0';
if(ch=='=')
{
buf[rlength].val[0]='<';
buf[rlength].val[1]='=';
buf[rlength].val[2]='\0';
}
else
{
buf[rlength].val[0]='<';
buf[rlength].val[1]='\0';
pline--;
}
rlength++;
break;
case '>':
readch();
buf[rlength].sig[0]='r';
buf[rlength].sig[1]='l';
buf[rlength].sig[2]='o';
buf[rlength].sig[3]='p';
buf[rlength].sig[4]='\0';
if(ch=='=')
{
buf[rlength].val[0]='>';
buf[rlength].val[1]='=';
buf[rlength].val[2]='\0';
}
else
{
buf[rlength].val[0]='>';
buf[rlength].val[1]='\0';
pline--;
}
rlength++;
break;
case '=':
readch();
if(ch=='=')
{
buf[rlength].sig[0]='r';
buf[rlength].sig[1]='l';
buf[rlength].sig[2]='o';
buf[rlength].sig[3]='p';
buf[rlength].sig[4]='\0';
buf[rlength].val[0]='=';
buf[rlength].val[1]='=';
buf[rlength].val[2]='\0';
}
else
{
buf[rlength].sig[0]='=';
buf[rlength].sig[1]='\0';
pline--;
}
rlength++;
break;
case '%':
readch();
if(ch=='=')
{
buf[rlength].sig[0]='%';
buf[rlength].sig[1]='=';
buf[rlength].sig[2]='\0';
}
else
{
buf[rlength].sig[0]='%';
buf[rlength].sig[1]='\0';
pline--;
}
rlength++;
break;
case '|':
readch();
if(ch=='|')
{
buf[rlength].sig[0]='o';
buf[rlength].sig[1]='r';
buf[rlength].sig[2]='\0';
rlength++;
}
else
{
cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行|字符错误"<<endl;
misnum++;
pline--;
}
break;
case '&':
readch();
if(ch=='&')
{
buf[rlength].sig[0]='a';
buf[rlength].sig[1]='n';
buf[rlength].sig[2]='d';
buf[rlength].sig[3]='\0';
rlength++;
}
else
{
cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行&字符错误"<<endl;
misnum++;
pline--;
}
break;
default:
cout<<"错误"<<misnum<<":"<<"第"<<linenum<<"行"<<ch<<"字符错误"<<endl;
misnum++;
break;
}
if(end!=EOF)
readch();
}
cout<<"共有"<<misnum<<"个错误!"<<endl;
cout<<"词法分析结束!"<<endl;
}
/**************分析结果输出函数******************/
void save()
{
saveFile<<"词法分析结果如下:"<<'\n';
for(int i=0;i<rlength;i++)
{
int j=0;int m=0;
saveFile<<"(";
while(buf[i].sig[j]!='\0')
{
saveFile<<buf[i].sig[j];
j++;
}
saveFile<<",";
while(buf[i].val[m]!='\0')
{
saveFile<<buf[i].val[m];
m++;
}
saveFile<<")";
}
saveFile<<endl;
saveFile<<"标识符表如下:"<<endl;
saveFile<<"number"<<" "<<"name"<<" "<<"type"<<" "<<"address"<<'\n';
for(int x=0;x<slength;x++)
{
saveFile<<x<<" ";
for(int j=0;sign[x].name[j]!='\0';j++)
saveFile<<sign[x].name[j];
saveFile<<" "<<sign[x].type<<" "<<&sign[i].address<<'\n';
}
saveFile<<"常数表如下:"<<endl;
saveFile<<"number"<<" "<<"name"<<" "<<"value"<<'\n';
for(int k=0;k<nlength;k++)
{
saveFile<<k<<" ";
for(int j=0;number[k].name[j]!='\0';j++)
{
saveFile<<number[k].name[j];
}
saveFile<<" "<<number[k].value<<'\n';
}
}
/*******************main()主函数*********************/
void main()
{
char filename1[128],filename2[128];
cout<<"请输入你要编译的源文件名称:"; //打开源程序文件
cin>>filename1;
openFile.open(filename1);
if(openFile.fail())
{
cout<<"打开文件失败!"<<endl;
return;
}
cout<<"请输入你要建立的目标文件名称:"; //建立记号文件
cin>>filename2;
saveFile.open(filename2);
init();
readch();
scanner();
openFile.close();
save();
saveFile.close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -