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