1. 程式人生 > >C++實現詞法分析器(學習)

C++實現詞法分析器(學習)

參考網上程式,我把生成的資料存在檔案裡,能分析C語言的源程式

#include<fstream>  
#include <iostream>  
#include <stdlib.h>  
#include <stdio.h>  
using namespace std;  
string KEYWORD[17]={"if","else","void","return","while","struct","for","do","int", //關鍵字  
                    "char","double","float","case"
,"sizeof","break","swicth","default"}; char SEPARATER[10]={';',',','{','}','[',']','(',')','"','#'}; //分隔符 char OPERATOR[11]={'+','-','*','/','>','<','=','!','%',':','?'}; //運算子 char FILTER[4]={' ','\t','\r','\n'}; //過濾符 const int IDENTIFIER=100; //識別符號值 const int
CONSTANT=101; //常數值 const int FILTER_VALUE=102; //過濾字元值 /**判斷是否為關鍵字**/ bool IsKeyword(string word){ for(int i=0;i<17;i++){ if(KEYWORD[i]==word){ return true; } } return false; } /**判斷是否為分隔符**/ bool IsSeparater(char ch){ for
(int i=0;i<10;i++){ if(SEPARATER[i]==ch){ return true; } } return false; } /**判斷是否為運算子**/ bool IsOperator(char ch){ for(int i=0;i<11;i++){ if(OPERATOR[i]==ch){ return true; } } return false; } /**判斷是否為過濾符**/ bool IsFilter(char ch){ for(int i=0;i<4;i++){ if(FILTER[i]==ch){ return true; } } return false; } /**判斷是否為大寫字母**/ bool IsUpLetter(char ch){ if(ch>='A' && ch<='Z') return true; return false; } /**判斷是否為小寫字母**/ bool IsLowLetter(char ch){ if(ch>='a' && ch<='z') return true; return false; } /**判斷是否為數字**/ bool IsDigit(char ch){ if(ch>='0' && ch<='9') return true; return false; } /**返回每個字的值**/ template <class T> int value(T *a,int n,T str){ for(int i=0;i<n;i++){ if(a[i]==str) return i+1; } return -1; } /**詞法分析**/ void analyse(FILE * fpin){ ofstream fout("out.txt"); char ch=' '; string arr=""; while((ch=fgetc(fpin))!=EOF) { arr=""; if(IsFilter(ch)) {} //判斷是否為過濾符 else if(IsLowLetter(ch)) { //判斷是否為關鍵字 while(IsLowLetter(ch)) { arr += ch; ch=fgetc(fpin); } //fseek(fpin,-1L,SEEK_CUR); if(IsKeyword(arr)) { printf("%3d ",value(KEYWORD,17,arr)); cout<<arr<<" 關鍵字"<<endl; fout<<"<"<<value(KEYWORD,17,arr)<<" "<<arr<<" "<<"關鍵字>\n"; } else { printf("%3d ",IDENTIFIER); cout<<arr<<" 識別符號"<<endl; fout<<"<"<<IDENTIFIER<<" "<<arr<<" "<<"識別符號>\n"; } } else if(IsDigit(ch)) { //判斷是否為數字 while(IsDigit(ch)||(ch=='.'&&IsDigit(fgetc(fpin)))) { arr += ch; ch=fgetc(fpin); } fseek(fpin,-1L,SEEK_CUR); printf("%3d ",CONSTANT); cout<<arr<<" 整形數"<<endl; fout<<"<"<<CONSTANT<<" "<<arr<<" "<<"整形數>\n"; } else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_') { while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)) { arr += ch; ch=fgetc(fpin); } fseek(fpin,-1L,SEEK_CUR); printf("%3d ",CONSTANT); cout<<arr<<" 識別符號"<<endl; fout<<"<"<<CONSTANT<<" "<<arr<<" "<<"識別符號>\n"; } else switch(ch) { case '+': case '-': case '*': case '/': case '>': case '<': case '=': case '!': case ':': case '?': case '%': { arr += ch; printf("%3d ",value(OPERATOR,11,*arr.data())); cout<<arr<<" 運算子"<<endl; fout<<"<"<<value(OPERATOR,11,*arr.data())<<" "<<arr<<" "<<"運算子>\n"; break; } case ';': case ',': case '(': case ')': case '[': case ']': case '{': case '}': case '"': case '#': { arr += ch; printf("%3d ",value(SEPARATER,10,*arr.data())); cout<<arr<<" 分隔符"<<endl; fout<<"<"<<value(SEPARATER,10,*arr.data())<<" "<<arr<<" "<<"分隔符>\n"; break; } default : { arr += ch; cout<<"\""<<arr<<"\":無法識別的字元!\n"<<endl; fout<<"<無法識別的字元!>\n"; } } } fout.close(); } int main() { char inFile[40]; FILE *fpin; cout<<"請輸入原始檔名(包括路徑和字尾):"; while(true){ cin>>inFile; if((fpin=fopen(inFile,"r"))!=NULL) break; else{ cout<<"檔名錯誤!"<<endl; cout<<"請輸入原始檔名(包括路徑和字尾):"; } } cout<<"------詞法分析如下------"<<endl; analyse(fpin); return 0; }