词法分析器就是通过扫描一段程序判断是否是关键字、标识符、常数、分界符、运算符。一般分为一符一种和经典五中;
这里我用的是经典五中,此词法分析器是用c++编写的;
/*
保留字|关键字:1
操作符|运算符:2
分界符:3
标识符:4
常数:5
无识别:6
*/
主要代码为:
#include<iostream>
using namespace std;
#define MAX 10
/*
保留字|关键字:1
操作符|运算符:2
分界符:3
标识符:4
常数:5
无识别:6
*/
char ch = ' ';
char* keyWord[10] = {"void","main","break","include","begin","end","if","else","while","switch"};
char token[20];//定义获取的字符
//判断是否是关键字
bool isKey(char * token)
{
for(int i = 0;i < MAX;i++)
{
if(strcmp(token,keyWord[i]) == 0)
return true;
}
return false;
}
//判断是否是字母
bool isLetter(char letter)
{
if((letter >= 'a' && letter <= 'z')||(letter >= 'A' && letter <= 'Z'))
return true;
else
return false;
}
//判断是否是数字
bool isDigit(char digit)
{
if(digit >= '0' && digit <= '9')
return true;
else
return false;
}
//词法分析
void analyze(FILE *fpin)
{
while((ch = fgetc(fpin)) != EOF){
if(ch == ' '||ch == '\t'||ch == '\n'){}
else if(isLetter(ch)){
char token[20]={'\0'};
int i=0;
while(isLetter(ch)||isDigit(ch)){
token[i] = ch;
i++;
ch = fgetc(fpin);
}
//回退一个指针
fseek(fpin,-1L,SEEK_CUR);
if(isKey(token)){
//关键字
cout<<token<<"\t1"<<"\t关键字"<<endl;
}
else{
//标识符
cout<<token<<"\t4"<<"\t标识符"<<endl;
}
}
else if(isDigit(ch)||(ch == '.'))
{
int i=0;
char token[20]={'\0'};
while(isDigit(ch)||(ch == '.'&&isDigit(fgetc(fpin))))
{
if(ch == '.')fseek(fpin,-1L,SEEK_CUR);
token[i] = ch;
i++;
ch = fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
//属于无符号常数
cout<<token<<"\t5"<<"\t常数"<<endl;
}
else switch(ch){
//运算符
case '+':{
ch = fgetc(fpin);
if(ch == '+')cout<<"++"<<"\t2"<<"\t运算符"<<endl;
else {
cout<<"+"<<"\t2"<<"\t运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);
}
}break;
case '-':{
ch = fgetc(fpin);
if(ch == '-')cout<<"--"<<"\t2"<<"\t运算符"<<endl;
else {
cout<<"-"<<"\t2"<<"\t运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);
}
}break;
case '*':cout<<ch<<"\t2"<<"\t运算符"<<endl;break;
case '/':cout<<ch<<"\t2"<<"\t运算符"<<endl;break;
//分界符
case '(':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
case ')':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
case '[':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
case ']':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
case ';':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
case '{':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
case '}':cout<<ch<<"\t3"<<"\t分界符"<<endl;break;
//运算符
case '=':{
ch = fgetc(fpin);
if(ch == '=')cout<<"=="<<"\t2"<<"\t运算符"<<endl;
else {
cout<<"="<<"\t2"<<"\t运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);
}
}break;
case ':':{
ch = fgetc(fpin);
if(ch == '=')cout<<":="<<"\t2"<<"\t运算符"<<endl;
else {
cout<<":"<<"\t2"<<"\t运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);
}
}break;
case '>':{
ch = fgetc(fpin);
if(ch == '=')cout<<">="<<"\t2"<<"\t运算符"<<endl;
else {
cout<<">"<<"\t2"<<"\t运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);
}
}break;
case '<':{
ch = fgetc(fpin);
if(ch == '=')cout<<"<="<<"\t2"<<"\t运算符"<<endl;
else {
cout<<"<"<<"\t2"<<"\t运算符"<<endl;
fseek(fpin,-1L,SEEK_CUR);
}
}break;
//无识别
default: cout<<ch<<"\t6"<<"\t无识别符"<<endl;
}
}
}
int main(){
char input[30];
FILE *fpin;
cout<<"请输入源文件名:\n"<<endl;
for(;;){
cin>>input;
if((fpin = fopen(input,"r")) != NULL)
break;
else
cout<<"路径输入错误"<<endl;
}
cout<<"****************词法分析结果********************"<<endl;
analyze(fpin);
fclose(fpin);
}
运行结果: