詞法分析器就是通過掃描一段程序判斷是否是關鍵字、標識符、常數、分界符、運算符。一般分為一符一種和經典五中;
這里我用的是經典五中,此詞法分析器是用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);
}
運行結果:



