寫一個編譯器,首先要知道的就是什麼是編譯器,我以爲能看到我這篇文章的基本上都知道了。我認爲,編譯器就是node
讓計算機讀懂代碼的程序,在這個程序裏,定義了各類規則(編程語言的語法),只要人們按照這個規則和計算機說ios
話(編程)就能讓計算機懂得咱們想幹嗎。編程
編譯器包括幾個模塊,也能夠說是過程,即詞法分析,語法分析,中間代碼生成等等。好吧我認可我知道的不清楚,數組
不過萬物起源詞法分析(我編的)必定沒問題。這裏咱們就先來第一步,詞法分析。詞法分析是編譯器中比較簡單的模塊了,數據結構
也是最基礎的模塊。它的做用就是將輸入的程序文本文件切割成一個一個的單詞和符號,以便接下來的模塊使用。編程語言
好了,高深的道理就不講了,我如今的目標就是要寫一個函數,這個函數接收一個文件地址,將該文件中的代碼分割ide
成單詞和符號,每一個單詞和符號被稱爲一個token,返回一個鏈表,存儲全部的token。函數定義就寫爲:函數
TokenList_tag LexExcute(string sourcefilepath);//TokenList_tag是鏈表頭指針,指向頭節點,sourcefilepath爲源文件地址
我將詞法分析程序寫在lex.cpp文件中,二話不說先上幾行代碼,頓時感受自信心爆棚。代碼4-7行能夠用一行this
using namespace std;代替spa
1 #include<iostream> 2 #include<string > 3 #include<fstream> 4 using std::cout; 5 using std::string; 6 using std::endl; 7 using std::ifstream;
講道理如今應該先定義一下token了,不過我還不知道token怎麼定義,就先不這麼搞了,先解決讀取文件的問題,
定義一個string變量(filepath)存儲文件地址,定義文件流(in)用於讀取文件內容,而後從流中每次讀取一行,存入
字符串變量line_str,這樣思路就很清晰了,咱們從line_str中逐個取出字符,而後分析。
1 ifstream in;//文件流 2 string filepath;//文件路徑 3 string line_str;//存儲每次讀出的行 4 int line_len;//讀出行的長度 5 int line_pos;//逐字符處理時,用於記錄位置 6 int line_num;//記錄當前源文件第幾行,可能之後報語法錯誤的時候有用 7 char ch;//逐字符處理時,記錄當前字符 8 string token_str;//記錄token字符串
爲防止出錯,咱們定義初始化函數init(),將全部變量的初始化放在該函數中,以下:
1 void init() 2 { 3 cout<<"func enter: init"<<endl; 4 line_pos=0; 5 line_num=0; 6 token_str=""; 7 ch='\0'; 8 //end_of_file=false; 9 //end_of_lex=false; 10 //tokenlist=new TokenNode_tag; 11 //tokenlist->token_str="#"; 12 //tokenlist->next=NULL; 13 //listtail=tokenlist; 14 in.open(filepath.c_str()); 15 cout<<"func end: init"<<endl; 16 }
在此函數執行以前,filepath就已經在函數外賦值了,我懶得傳參數,就在該函數調用前加了一句:
filepath=sourcefilepath; //sourcefilepath是傳進來的參數。
下面,咱們就開始定義token數據結構,目前我能想到的數據結構屬性只有兩個,一個token_str,
一個token_type。token_str用來保存token字符串,而token_type記錄該token是什麼類型,好比標識符,
關鍵字,數字等等。在定義token前先定義TokenType(枚舉類型),以下:
1 enum TokenType 2 { 3 //順序不可改變 4 KEYWORDS_INT, 5 KEYWORDS_DOUBLE, 6 KEYWORDS_FLOAT, 7 KEYWORDS_IF, 8 KEYWORDS_ELSE, 9 KEYWORDS_ELSIF, 10 KEYWORDS_WHILE, 11 KEYWORDS_FOR, 12 13 14 IDENTIFY, 15 OP_EQUAL,//== 16 OP_ASSIGN,//= 17 OP_LP,//( 18 OP_RP,//) 19 OP_ADD,//+ 20 OP_SUB,//- 21 OP_MUL,//* 22 OP_DIV,// / 23 OP_SEMI,//; 24 NUM_FLOAT, 25 NUM_INT 26 };
TokenType裏面的註釋確定就很清晰了,就很少介紹,下面就是TokenNode的定義:
1 typedef struct TokenNode_tag 2 { 3 string token_str; 4 TokenType token_type; 5 struct TokenNode_tag *next;//用於製做鏈表 6 }*TokenList_tag,TokenNode_tag;
可能會有人疑惑,命名爲何要加一個tag呢?首先,名字是什麼都無所謂(關鍵字除外),其次
加一個tag是爲了區別內部使用和外部調用,所謂內部就是lex.cpp中的函數使用,外部就是爲了之後的
其餘模塊調用(到時候會給這些結構從新起名爲TokenNode)。
好了,萬事俱備,只欠最關鍵的函數了:
1 TokenList_tag LexExcute(string sourcefilepath) 2 { 3 cout<<"func enter: main"<<endl; 4 filepath=sourcefilepath;//; 5 init();
//這裏將寫關鍵代碼,一個大while循環 6 cout<<"func end: main"<<endl; 7 }
這個函數做爲主函數,他的工做原理就是循環從line_str中取出字符,而後根據字符判斷目前是否是一個單詞
或符號,好比出現空格就說明字符串結束等(說法不許確)。好吧,我知道這裏有個自動機什麼的,我也講不清楚,
下面直接說個人實現方法:
我將詞法分析運做過程分爲幾個階段,每一個階段都用一種狀態記錄,好比說,當while大循環第一次運做的時候,
此時爲初始狀態(STATUS_NON),在這個狀態下若取出字符ch爲數字(0-9),那麼詞法分析狀態就轉變爲數字
態(STATUS_NUM),在該狀態下若取出字符ch爲數字則狀態不變,若ch爲 ‘.’ (小數點)說明數字爲浮點型,狀態轉爲浮點
態(STATUS_FLOAT),若ch爲空或者其餘字符,說明數字結束,狀態轉爲初始態,開始下一個循環。
可能我本身以爲講的挺清晰,看到的人反而有困難,不如我就畫個圖:
好吧,真是不畫不知道本身畫多醜,不過拋開這些仍是挺清晰的吧。。。額,這不重要,這應該就有傳說
中的自動機的影子了吧,好吧,不強求能不能看懂了,最下面會有函數完整代碼,看懂代碼確定就沒問題了。
在寫主函數(LexExcute)以前,咱們還要作一些必要工做:
1 bool end_of_file;//初始爲false,當讀取文件結束的時候置爲true 2 bool end_of_lex;//當讀取文件結束,而其當前行也分析完畢時置爲true(詞法分析結束標誌) 3 TokenList_tag tokenlist;//詞法分析器執行結束後產生的 token 串(主函數返回鏈表的頭指針) 4 TokenNode_tag*listtail;//鏈表尾指針,用於尾部插入節點 5 void getline();//文件中讀取一行 6 void getch();//獲取一個字符 7 bool ischar();//是否爲a-z或者A-Z 8 bool isnum();//是否爲0-9 9 void concat();//鏈接到token_str
10 // 11 void backwords();//回退一個字符 12 void tokenlist_insert(TokenNode_tag*);//鏈表插入函數 13 void tokenlist_visit();//鏈表遍歷函數,用於檢查正誤,對功能沒用用 14 int iskeywords(string );//判斷是不是關鍵字
關鍵字數組,自動機狀態定義具體函數實現就看下面的完整代碼吧:
1 string keywords[]= 2 { 3 //順序不可改變 4 "int", 5 "double", 6 "float", 7 "if", 8 "else", 9 "elsif", 10 "while", 11 "for" 12 }; 13 14 enum LexStatus 15 { 16 STATUS_NON, 17 STATUS_NUM, 18 STATUS_STR, 19 STATUS_FLOAT, 20 STATUS_ASSIGN, 21 22 };
1 TokenList_tag LexExcute(string sourcefilepath) 2 { 3 cout<<"func enter: main"<<endl; 4 filepath=sourcefilepath;//; 5 init(); 6 getline(); 7 LexStatus lexstatus=STATUS_NON; 8 TokenNode_tag *tokennode; 9 while(!end_of_lex) 10 { 11 getch(); 12 if(lexstatus==STATUS_NON)//初始狀態下 13 { 14 cout<<"LexStatus: STATUS_NON"<<endl; 15 if(ischar()||ch=='_') 16 { 17 lexstatus=STATUS_STR; 18 cout<<"LexStatus: STATUS_NON -> STATUS_STR"<<endl; 19 concat(); 20 21 } 22 else if(isnum()) 23 { 24 lexstatus=STATUS_NUM; 25 cout<<"LexStatus: STATUS_NON -> STATUS_NUM"<<endl; 26 concat(); 27 } 28 else if(ch=='(') 29 { 30 concat(); 31 tokennode=new TokenNode_tag; 32 tokennode->token_str=token_str; 33 tokennode->token_type=OP_LP; 34 tokennode->next=NULL; 35 tokenlist_insert(tokennode); 36 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 37 lexstatus=STATUS_NON; 38 token_str=""; 39 } 40 else if(ch==')') 41 { 42 concat(); 43 tokennode=new TokenNode_tag; 44 tokennode->token_str=token_str; 45 tokennode->token_type=OP_RP; 46 tokennode->next=NULL; 47 tokenlist_insert(tokennode); 48 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 49 lexstatus=STATUS_NON; 50 token_str=""; 51 } 52 else if(ch==' ') 53 { 54 cout<<"do nothing"<<endl; 55 } 56 else if(ch=='\n') 57 { 58 cout<<"do nothing"<<endl; 59 } 60 else if(ch=='=') 61 { 62 concat(); 63 cout<<"LexStatus: STATUS_NON -> STATUS_ASSIGN"<<endl; 64 lexstatus=STATUS_ASSIGN; 65 token_str=""; 66 } 67 else if(ch=='+') 68 { 69 concat(); 70 tokennode=new TokenNode_tag; 71 tokennode->token_str=token_str; 72 tokennode->token_type=OP_ADD; 73 tokennode->next=NULL; 74 tokenlist_insert(tokennode); 75 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 76 lexstatus=STATUS_NON; 77 token_str=""; 78 79 } 80 else if(ch=='-') 81 { 82 concat(); 83 tokennode=new TokenNode_tag; 84 tokennode->token_str=token_str; 85 tokennode->token_type=OP_SUB; 86 tokennode->next=NULL; 87 tokenlist_insert(tokennode); 88 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 89 lexstatus=STATUS_NON; 90 token_str=""; 91 } 92 else if(ch=='*') 93 { 94 concat(); 95 tokennode=new TokenNode_tag; 96 tokennode->token_str=token_str; 97 tokennode->token_type=OP_MUL; 98 tokennode->next=NULL; 99 tokenlist_insert(tokennode); 100 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 101 lexstatus=STATUS_NON; 102 token_str=""; 103 } 104 else if(ch=='/') 105 { 106 concat(); 107 tokennode=new TokenNode_tag; 108 tokennode->token_str=token_str; 109 tokennode->token_type=OP_DIV; 110 tokennode->next=NULL; 111 tokenlist_insert(tokennode); 112 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 113 lexstatus=STATUS_NON; 114 token_str=""; 115 } 116 else if(ch==';') 117 { 118 concat(); 119 tokennode=new TokenNode_tag; 120 tokennode->token_str=token_str; 121 tokennode->token_type=OP_SEMI; 122 tokennode->next=NULL; 123 tokenlist_insert(tokennode); 124 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 125 lexstatus=STATUS_NON; 126 token_str=""; 127 } 128 129 }//lexstatus 130 else if(lexstatus==STATUS_ASSIGN) 131 { 132 if(ch=='=')//== 133 { 134 concat(); 135 tokennode=new TokenNode_tag; 136 tokennode->token_str=token_str; 137 tokennode->token_type=OP_EQUAL; 138 tokennode->next=NULL; 139 tokenlist_insert(tokennode); 140 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl; 141 lexstatus=STATUS_NON; 142 token_str=""; 143 } 144 else //= 145 { 146 tokennode=new TokenNode_tag; 147 tokennode->token_str=token_str; 148 tokennode->token_type=OP_ASSIGN; 149 tokennode->next=NULL; 150 tokenlist_insert(tokennode); 151 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl; 152 lexstatus=STATUS_NON; 153 token_str=""; 154 backwords(); 155 } 156 } 157 else if(lexstatus==STATUS_FLOAT) 158 { 159 if(isnum()) 160 { 161 concat(); 162 } 163 else 164 { 165 tokennode=new TokenNode_tag; 166 tokennode->token_str=token_str; 167 tokennode->token_type=NUM_FLOAT; 168 tokennode->next=NULL; 169 tokenlist_insert(tokennode); 170 cout<<"LexStatus: STATUS_FLOAT -> STATUS_NON"<<endl; 171 lexstatus=STATUS_NON; 172 token_str=""; 173 backwords(); 174 } 175 } 176 else if(lexstatus==STATUS_NUM) 177 { 178 if(isnum()) 179 { 180 concat(); 181 } 182 else if(ch=='.') 183 { 184 concat(); 185 lexstatus=STATUS_FLOAT; 186 } 187 else 188 { 189 tokennode=new TokenNode_tag; 190 tokennode->token_str=token_str; 191 tokennode->token_type=NUM_INT; 192 tokennode->next=NULL; 193 tokenlist_insert(tokennode); 194 cout<<"LexStatus: STATUS_NUM -> STATUS_NON"<<endl; 195 lexstatus=STATUS_NON; 196 token_str=""; 197 backwords(); 198 } 199 } 200 else if(lexstatus==STATUS_STR) 201 { 202 if(ischar()||ch=='_'||isnum()) 203 { 204 concat(); 205 } 206 else 207 { 208 tokennode=new TokenNode_tag; 209 tokennode->token_str=token_str; 210 int check=iskeywords(token_str); 211 if(check!=-1)tokennode->token_type=(TokenType)check; 212 else tokennode->token_type=IDENTIFY; 213 tokennode->next=NULL; 214 tokenlist_insert(tokennode); 215 cout<<"LexStatus: STATUS_STR -> STATUS_NON"<<endl; 216 lexstatus=STATUS_NON; 217 token_str=""; 218 backwords(); 219 } 220 } 221 222 223 224 } 225 226 cout<<"func end: main"<<endl; 227 tokenlist_visit(); 228 return tokenlist; 229 }
完整代碼:(代碼是從好多文件剪出來的,應該能夠運行吧,額。。。)感受代碼好長,高手應該用很短就好了吧,慚愧。
1 #include<iostream> 2 #include<string > 3 #include<fstream> 4 using std::cout; 5 using std::string; 6 using std::endl; 7 using std::ifstream; 8 string keywords[]= 9 { 10 //順序不可改變 11 "int", 12 "double", 13 "float", 14 "if", 15 "else", 16 "elsif", 17 "while", 18 "for" 19 }; 20 21 enum LexStatus 22 { 23 STATUS_NON, 24 STATUS_NUM, 25 STATUS_STR, 26 STATUS_FLOAT, 27 STATUS_ASSIGN, 28 29 }; 30 enum TokenType 31 { 32 //順序不可改變 33 KEYWORDS_INT, 34 KEYWORDS_DOUBLE, 35 KEYWORDS_FLOAT, 36 KEYWORDS_IF, 37 KEYWORDS_ELSE, 38 KEYWORDS_ELSIF, 39 KEYWORDS_WHILE, 40 KEYWORDS_FOR, 41 42 43 IDENTIFY, 44 OP_EQUAL,//== 45 OP_ASSIGN,//= 46 OP_LP,//( 47 OP_RP,//) 48 OP_ADD,//+ 49 OP_SUB,//- 50 OP_MUL,//* 51 OP_DIV,// / 52 OP_SEMI,//; 53 NUM_FLOAT, 54 NUM_INT 55 }; 56 typedef struct TokenNode_tag 57 { 58 string token_str; 59 TokenType token_type; 60 struct TokenNode_tag *next; 61 }*TokenList_tag,TokenNode_tag; 62 63 64 ifstream in; 65 string filepath; 66 string line_str; 67 int line_len; 68 int line_pos; 69 int line_num; 70 char ch; 71 string token_str; 72 73 bool end_of_file; 74 bool end_of_lex; 75 TokenList_tag tokenlist;//詞法分析器執行結束後產生的 token 串 76 TokenNode_tag*listtail; 77 void init(); 78 void getline(); 79 void getch(); 80 bool ischar(); 81 bool isnum(); 82 void concat(); 83 void backwords(); 84 void tokenlist_insert(TokenNode_tag*); 85 void tokenlist_visit(); 86 int iskeywords(string ); 87 TokenList_tag LexExcute(string sourcefilepath) 88 { 89 cout<<"func enter: main"<<endl; 90 filepath=sourcefilepath;//; 91 init(); 92 getline(); 93 LexStatus lexstatus=STATUS_NON; 94 TokenNode_tag *tokennode; 95 while(!end_of_lex) 96 { 97 getch(); 98 if(lexstatus==STATUS_NON)//初始狀態下 99 { 100 cout<<"LexStatus: STATUS_NON"<<endl; 101 if(ischar()||ch=='_') 102 { 103 lexstatus=STATUS_STR; 104 cout<<"LexStatus: STATUS_NON -> STATUS_STR"<<endl; 105 concat(); 106 107 } 108 else if(isnum()) 109 { 110 lexstatus=STATUS_NUM; 111 cout<<"LexStatus: STATUS_NON -> STATUS_NUM"<<endl; 112 concat(); 113 } 114 else if(ch=='(') 115 { 116 concat(); 117 tokennode=new TokenNode_tag; 118 tokennode->token_str=token_str; 119 tokennode->token_type=OP_LP; 120 tokennode->next=NULL; 121 tokenlist_insert(tokennode); 122 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 123 lexstatus=STATUS_NON; 124 token_str=""; 125 } 126 else if(ch==')') 127 { 128 concat(); 129 tokennode=new TokenNode_tag; 130 tokennode->token_str=token_str; 131 tokennode->token_type=OP_RP; 132 tokennode->next=NULL; 133 tokenlist_insert(tokennode); 134 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 135 lexstatus=STATUS_NON; 136 token_str=""; 137 } 138 else if(ch==' ') 139 { 140 cout<<"do nothing"<<endl; 141 } 142 else if(ch=='\n') 143 { 144 cout<<"do nothing"<<endl; 145 } 146 else if(ch=='=') 147 { 148 concat(); 149 cout<<"LexStatus: STATUS_NON -> STATUS_ASSIGN"<<endl; 150 lexstatus=STATUS_ASSIGN; 151 token_str=""; 152 } 153 else if(ch=='+') 154 { 155 concat(); 156 tokennode=new TokenNode_tag; 157 tokennode->token_str=token_str; 158 tokennode->token_type=OP_ADD; 159 tokennode->next=NULL; 160 tokenlist_insert(tokennode); 161 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 162 lexstatus=STATUS_NON; 163 token_str=""; 164 165 } 166 else if(ch=='-') 167 { 168 concat(); 169 tokennode=new TokenNode_tag; 170 tokennode->token_str=token_str; 171 tokennode->token_type=OP_SUB; 172 tokennode->next=NULL; 173 tokenlist_insert(tokennode); 174 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 175 lexstatus=STATUS_NON; 176 token_str=""; 177 } 178 else if(ch=='*') 179 { 180 concat(); 181 tokennode=new TokenNode_tag; 182 tokennode->token_str=token_str; 183 tokennode->token_type=OP_MUL; 184 tokennode->next=NULL; 185 tokenlist_insert(tokennode); 186 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 187 lexstatus=STATUS_NON; 188 token_str=""; 189 } 190 else if(ch=='/') 191 { 192 concat(); 193 tokennode=new TokenNode_tag; 194 tokennode->token_str=token_str; 195 tokennode->token_type=OP_DIV; 196 tokennode->next=NULL; 197 tokenlist_insert(tokennode); 198 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 199 lexstatus=STATUS_NON; 200 token_str=""; 201 } 202 else if(ch==';') 203 { 204 concat(); 205 tokennode=new TokenNode_tag; 206 tokennode->token_str=token_str; 207 tokennode->token_type=OP_SEMI; 208 tokennode->next=NULL; 209 tokenlist_insert(tokennode); 210 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl; 211 lexstatus=STATUS_NON; 212 token_str=""; 213 } 214 215 }//lexstatus 216 else if(lexstatus==STATUS_ASSIGN) 217 { 218 if(ch=='=')//== 219 { 220 concat(); 221 tokennode=new TokenNode_tag; 222 tokennode->token_str=token_str; 223 tokennode->token_type=OP_EQUAL; 224 tokennode->next=NULL; 225 tokenlist_insert(tokennode); 226 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl; 227 lexstatus=STATUS_NON; 228 token_str=""; 229 } 230 else //= 231 { 232 tokennode=new TokenNode_tag; 233 tokennode->token_str=token_str; 234 tokennode->token_type=OP_ASSIGN; 235 tokennode->next=NULL; 236 tokenlist_insert(tokennode); 237 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl; 238 lexstatus=STATUS_NON; 239 token_str=""; 240 backwords(); 241 } 242 } 243 else if(lexstatus==STATUS_FLOAT) 244 { 245 if(isnum()) 246 { 247 concat(); 248 } 249 else 250 { 251 tokennode=new TokenNode_tag; 252 tokennode->token_str=token_str; 253 tokennode->token_type=NUM_FLOAT; 254 tokennode->next=NULL; 255 tokenlist_insert(tokennode); 256 cout<<"LexStatus: STATUS_FLOAT -> STATUS_NON"<<endl; 257 lexstatus=STATUS_NON; 258 token_str=""; 259 backwords(); 260 } 261 } 262 else if(lexstatus==STATUS_NUM) 263 { 264 if(isnum()) 265 { 266 concat(); 267 } 268 else if(ch=='.') 269 { 270 concat(); 271 lexstatus=STATUS_FLOAT; 272 } 273 else 274 { 275 tokennode=new TokenNode_tag; 276 tokennode->token_str=token_str; 277 tokennode->token_type=NUM_INT; 278 tokennode->next=NULL; 279 tokenlist_insert(tokennode); 280 cout<<"LexStatus: STATUS_NUM -> STATUS_NON"<<endl; 281 lexstatus=STATUS_NON; 282 token_str=""; 283 backwords(); 284 } 285 } 286 else if(lexstatus==STATUS_STR) 287 { 288 if(ischar()||ch=='_'||isnum()) 289 { 290 concat(); 291 } 292 else 293 { 294 tokennode=new TokenNode_tag; 295 tokennode->token_str=token_str; 296 int check=iskeywords(token_str); 297 if(check!=-1)tokennode->token_type=(TokenType)check; 298 else tokennode->token_type=IDENTIFY; 299 tokennode->next=NULL; 300 tokenlist_insert(tokennode); 301 cout<<"LexStatus: STATUS_STR -> STATUS_NON"<<endl; 302 lexstatus=STATUS_NON; 303 token_str=""; 304 backwords(); 305 } 306 } 307 308 309 310 } 311 312 cout<<"func end: main"<<endl; 313 tokenlist_visit(); 314 return tokenlist; 315 }//main 316 int iskeywords(string str) 317 { 318 int i=0; 319 int len=sizeof(keywords)/sizeof(string); 320 cout<<"length of keyword[]: "<<len<<endl; 321 while(i<len) 322 { 323 if(str==keywords[i]) 324 { 325 cout<<str<<" is keywords"<<endl; 326 return i; 327 } 328 ++i; 329 } 330 cout<<str<<" isn't keywords"<<endl; 331 return -1; 332 } 333 void tokenlist_visit() 334 { 335 TokenNode_tag *tn; 336 tn=tokenlist; 337 while(tn->next!=NULL) 338 { 339 cout<<tn->next->token_str<<" token_type"<<tn->next->token_type<<endl; 340 tn=tn->next; 341 } 342 343 } 344 void tokenlist_insert(TokenNode_tag* token) 345 { 346 cout<<"func enter: tokenlist_insert"<<endl; 347 listtail->next=token; 348 listtail=listtail->next; 349 cout<<"func end: tokenlist_insert"<<endl; 350 } 351 bool ischar() 352 { 353 cout<<"func enter: ischar ->ch:"<<ch<<endl; 354 if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) 355 { 356 cout<<"func end: ischar ->"<<ch<<" is char"<<endl; 357 return true; 358 } 359 else 360 { 361 cout<<"func end: ischar ->"<<ch<<" isn't char"<<endl; 362 return false; 363 } 364 } 365 bool isnum() 366 { 367 cout<<"func enter: isnum ->ch:"<<ch<<endl; 368 if(ch>='0'&&ch<='9') 369 { 370 cout<<"func end: isnum ->"<<ch<<" is num"<<endl; 371 return true; 372 } 373 else 374 { 375 cout<<"func end: isnum ->"<<ch<<" isn't num"<<endl; 376 return false; 377 } 378 379 } 380 /** 381 將ch加到token_str後 382 */ 383 void concat() 384 { 385 cout<<"func enter: concat ->token:"<<token_str<<" ch:"<<ch<<endl; 386 token_str+=ch; 387 cout<<"func end: concat ->token:"<<token_str<<endl; 388 } 389 void backwords() 390 { 391 cout<<"func enter: backwords -> pos:"<<line_pos<<endl; 392 if(line_pos>0)line_pos--; 393 else cout<<"this is first ch in this line,can not backwords!"; 394 cout<<"func end: backwords -> pos:"<<line_pos<<endl; 395 } 396 void getch() 397 { 398 cout<<"func enter: getch"<<endl; 399 if(line_pos<line_len)//從當前行獲取一個字符 400 { 401 ch=line_str[line_pos++]; 402 cout<<"ch: "<<ch<<endl; 403 } 404 else//此行結束 405 { 406 cout<<"end of line"<<endl; 407 if(end_of_file) 408 { 409 cout<<"file over!!!"<<endl; 410 end_of_lex=true; 411 ch='\0';//結束標誌 412 } 413 else//文件並未結束,獲取新行 414 { 415 cout<<"new line"<<endl; 416 getline(); 417 getch(); 418 } 419 } 420 cout<<"func end: getch"<<endl; 421 } 422 void init() 423 { 424 cout<<"func enter: init"<<endl; 425 line_pos=0; 426 line_num=0; 427 token_str=""; 428 ch='\0'; 429 end_of_file=false; 430 end_of_lex=false; 431 tokenlist=new TokenNode_tag; 432 tokenlist->token_str="#"; 433 tokenlist->next=NULL; 434 listtail=tokenlist; 435 in.open(filepath.c_str()); 436 cout<<"func end: init"<<endl; 437 } 438 439 void getline() 440 { 441 cout<<"func enter: getline"<<endl; 442 if(in) 443 { 444 line_num++; 445 getline(in,line_str); 446 //in>>line_str; 447 line_str+='\n'; 448 line_len=line_str.length(); 449 if(line_len==0)cout<<"line"<<line_num<<": "<<line_str<<endl; 450 else 451 { 452 cout<<"line"<<line_num<<": "<<line_str<<endl; 453 cout<<"length: "<<line_len<<endl; 454 } 455 line_pos=0; 456 } 457 else 458 { 459 cout<<"end of file"<<endl; 460 end_of_file=true; 461 } 462 cout<<"func end: getline"<<endl; 463 }
歡迎發現錯誤,歡迎留言!!!