標籤:namespace switch cout 保留字 inf 運行 iostream 路徑 sdi
詞法分析器就是通過掃描一段程式判斷是否是關鍵字、標識符、常數、分界符、運算子。一般分為一符一種和經典五中;
這裡我用的是經典五中,此詞法分析器是用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;elsereturn false;}//判斷是否是數字bool isDigit(char digit){if(digit >= ‘0‘ && digit <= ‘9‘)return true;elsereturn 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);}
運行結果:
c++詞法分析器