📄 词法分析器.cpp
字号:
#include"stdio.h"
#include"stdlib.h"
#include"iostream.h"
#include"iomanip.h"
#include"fstream.h"
#include"string.h"
#define KEYWORD_NUM 34
#define OPERATES_NUM1 7
#define OPERATES_NUM2 6
#define LIMIT_NUM 8
int In_KeyWords(char * str,char * string[KEYWORD_NUM]);
int In_Limit_Words(char str, char string[LIMIT_NUM]);
int In_Operates1(char str, char string1[OPERATES_NUM1]);
int In_Operates2(char *str , char *string2[OPERATES_NUM2]);
void main()
{
FILE *fp; //记录读文件指针
char FileName[20];
char ch ,ch_add ; //ch记录当前输入的字符,ch_add记录当前输入的前一个字符(因为最长的运算符和界符占两个字符)
int count=0;
char tempstr[81]; //记录当前读入的字符串
int flag; //标志它是不是关键字
int notflag1=0 ; //标志它目前是不是已经出现了非法字符
int notflag2=0;
char * Keywords[KEYWORD_NUM]={"auto", "break", "case","char", //关键子的记号为1
"const","continue","default",
"do","double", "else","enum",
"extern","float","for","goto",
"if","int","long","register",
"return","short","signed","sizeof",
"static","struct","switch","typedef",
"union","unsigned","void","volatile",
"while","printf","scanf"}; // 定义关键字字符串数组
char Operates1[OPERATES_NUM1]={'+', '-', '*', '/', '>','<', //运算符的记号为2
'='};
char * Operates2[OPERATES_NUM2]={"<=",">=","==","!=","++","--"};
char Limit_Words[LIMIT_NUM]={';', ',', '(', ')', '[', ']', //界符的记号为3
'{', '}'}; //至于注释符/*则直接在程序中体现
//标识符的记号为4 ,常数的标识符为5
cout<<"请输入你要分析的文件的名称:";
cin>>FileName;
cout<<endl<<endl;
if((fp=fopen(FileName ,"r"))==NULL)
{
cout<<endl<<"文件打开失败!"<<endl;
exit(0); //打开测试文件
}
ch=fgetc(fp);
while(ch!=EOF)
{
while(ch==' ')
{
ch=fgetc(fp);
}
ch_add=ch;
ch=fgetc(fp);
if(In_Limit_Words(ch_add,Limit_Words)) //判断第一个字符就是不是界符
{
cout<<endl<<"< "<<ch_add;
cout<<" , 界符 >"<<endl;
}
if((In_Operates1(ch_add,Operates1))&&(ch!='*')&&(ch!='/')) //判断第一个字符就是不是操作符(此时需考虑注释符号)
{
cout<<endl<<"< "<<ch_add ;
cout<<" , 运算符 >"<<endl;
}
if(ch_add=='/'&& ch=='*') //略去注释部分
{
do
{
ch_add=ch;
ch=fgetc(fp);
if(ch_add=='/'&& ch=='*')
cout<<endl<<"错误!注释不能嵌套!!"<<endl;
}
while(!(ch_add=='*'&& ch=='/'));
}
if(In_Limit_Words(ch_add,Limit_Words)||(In_Operates1(ch_add,Operates1))&&(ch!='*')&&(ch!='/'))
{
fseek(fp,-1,1); //将文件读指针定位于第一个不是空格,界符,运算符的字符
fgets(tempstr,2,fp);
}
else
{
fseek(fp,-2,1); //将文件读指针定位于第一个不是空格的字符
fgets(tempstr,3,fp); //从当前位置读入两个有效字符,第三个字符读入的是“\0”
}
if(In_Operates2(tempstr,Operates2))
{
cout<<endl<<"< "<<tempstr ;
cout<<" , 运算符 >"<<endl;
}
//注意,此时文件的读指针位于第三个字符上
if(In_Limit_Words(ch_add,Limit_Words)||(In_Operates1(ch_add,Operates1))&&(ch!='*')&&(ch!='/'))
{
fseek(fp,-1,1); //将文件读指针定位于第一个不是空格,界符,运算符的字符
// fgets(tempstr,3,fp);
}
else
{
fseek(fp,-2,1); //将文件读指针定位于第一个不是空格的字符
//fgets(tempstr,3,fp); //从当前位置读入两个有效字符,第三个字符读入的是“\0”
}
// else fseek(fp,-2,1); //下面重新将文件读指针定位于第一个不是空格的字符
ch=fgetc(fp);
count=1;
if((ch>64&&ch<91)||(ch>96&&ch<123)||ch=='_') //标识符ID的可以使用的合法字符是字母和下划线
{
notflag1=0;
//ch=fgetc(fp);
while(ch!=' '&& ch!='!' &&(!In_Operates1(ch,Operates1))&&(!In_Limit_Words(ch,Limit_Words)) )
{
if(!(ch>64&&ch<91)&&!(ch>96&&ch<123)&&ch!='_')
notflag1=1;
count++;
ch=fgetc(fp);
}
fseek(fp, (0-(count)),1);
fgets(tempstr,(count),fp);
flag=In_KeyWords(tempstr,Keywords);
if(flag==0 && notflag1==0) //如果不是关键字且 没有出现非法字符
{
cout<<endl<<"< "<<tempstr ;
cout<<" , 标识符 >"<<endl;
}
else if(notflag1==1)
{
cout<<endl<<tempstr ;
cout<<"是非法字符串!"<<endl;
}
}
if(ch>47&&ch<58)
{
notflag2=0;
// ch=fgetc(fp);
while( ch!=' '&& ch!='!' &&(!In_Operates1(ch,Operates1))&&(!In_Limit_Words(ch,Limit_Words)))
{
if(ch<=47||ch>=58)
notflag2=1;
count++;
ch=fgetc(fp);
}
fseek(fp, (0-(count)),1);
fgets(tempstr,(count),fp);
if(notflag2==0) //如果不是关键字
{
cout<<endl<<"< "<<tempstr ;
cout<<" , 常数 >"<<endl;
}
else
{
cout<<endl<<"< "<<tempstr ;
cout<<"是非法字符串!"<<endl;
}
}
ch=fgetc(fp);
}
}
int In_KeyWords(char * str,char * string[KEYWORD_NUM])
{
for(int i=0;i<KEYWORD_NUM;i++)
{
if(!(strcmp(string[i],str)))
{
cout<<endl<<"< "<<str ;
cout<<" , 关键字 >"<<endl;
return 1;
}
}
if(i>=KEYWORD_NUM) return 0;
}
int In_Limit_Words(char str, char string[LIMIT_NUM])
{
for (int i=0;i<LIMIT_NUM;i++)
{
if ( str==string[i])
{
return 1;
break;
}
}
if(i>=LIMIT_NUM)
return 0;
}
int In_Operates1(char str, char string1 [OPERATES_NUM1])
{
for (int i=0;i<OPERATES_NUM1;i++)
{
if (str==string1[i])
{
return 1;
break;
}
}
if(i>=OPERATES_NUM1)
return 0;
}
int In_Operates2(char *str, char *string2[OPERATES_NUM2])
{
for (int i=0;i<OPERATES_NUM2;i++)
{
if (!(strcmp(string2[i],str)))
{
return 1;
break;
}
}
if(i<=OPERATES_NUM2)
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -