編譯器之詞法分析

2022-04-09 23:58:52 字數 4875 閱讀 1808

最近我們在做乙個有關snl語言的編譯器,下面寫了一下大概流程

詞法分析器是編譯過程的第一階段,功能是

1.對以字串形式輸入的源程式(這裡是把源程式從檔案讀出,也可以在控制台輸入)按順序進行掃瞄,根據snl語言的詞法規則識別具有獨立意義的單詞(符號)序列,

如保留字(由語言系統自身定義的,通常是由字母組成的字串),

識別符號(一般是由字母開頭,字母、數字,或其它符號的任意組合構成的,這裡snl是由字母開頭,後面加字母或數字組成的,分析起來較簡單),

常量(包括整數常數、 實數常數、字串常量等),

特殊符號(運算子和界限,運算子表示程 序中算術運算、邏輯運算、字元運算、賦值運算的確定的字元或字串)等,

並輸出與其等價的token序列(這裡將token序列儲存在了檔案中)。

2.報告詞法錯誤!

詞法錯誤:語言字母表以外的非法字元

(用確定有限自動機可以容易識別)

**幾個問題和處理方法**

1.保留字的識別

把保留字當作一般識別符號識別,然後查詢保留字表,就是這裡的lex表,如果有,把它當作保留字處理,如果沒有按一般識別符號處理。

2.復合單詞的識別   

有一類單詞是由兩個或者兩個以上符號組成的,有時字首部分也可以是乙個獨立的單詞

3.數的轉換  

詞法分析應把字串轉換成數,「123」看成123

4.向前看幾個字元的處理    

為了識別出乙個單詞需要向前看好幾個單詞

5.控制字元的處理  

1)無用的空格符和製表符刪掉(這裡是自動忽略)  

2)字串內的空格不能刪  

3)換行符不能直接刪除,用於錯誤定位

4)注釋   

源程式中的注釋沒有任何語法和語義上的意義,在進行詞法分析時可以直接將注釋忽略,不必生成token

5)直接在語義資訊部分儲存   

語義資訊的長度有限制時,直接將識別符號或常量本身儲存於token中的語義(語義資訊是為了 後面進行的語義分析和**生成提供資訊)

構造詞法分析器的步驟:   

1.確定詞法分析器的介面,即確定詞法分析器是作為語法分析的乙個子程式還是作為獨立一遍   

2.確定單次分類和token結構   

3.確定每一類單詞的描述正規表示式->nfa->dfa   

4.設計演算法實現dfa 單詞的內部表示:

token     token通常包含兩部分:token-type,attribute-value     token-type: 說明單詞的類別,為語法分析提供資訊     attribute-value:單詞的屬性,為語義分析和**生成提供資訊 (這裡  token包含4部分:在源程式中的行數,lex表中的詞法資訊編碼,語法資訊,語義資訊 這裡用確定有限自動機dfa識別符號串)

輸入:以eof作為結束符的符號串行    輸出:token序列

資料結構:

struct token45

*/6 #include "

scanner.h"7

char* lexstr =;

15char* word=;

33 tokennode::tokennode(int linenum,int code,const

char *lexinfor,const

char*semaninfor)

39 list::~list()45}

4647

bool list::outtofile(const

char *filename)

4860

fclose(file);

61return1;

62}63bool

list::outtoscreen()

6473

return1;

74}7576

bool list::insertnode(tokennode*p)

83else

89return

true;90

}9192 list* scanner::scanner(const

char* sourcefile,const

char*tokenfile)

100int linenum=1; //

從第一行開始

101bool flag=true

;102 tokennode*ptr;

103 list *list=new list;//

新建乙個tokenlist,用以儲存分析得到的token序列

104while

(flag)

148}

149150

fclose(fp);

151if(list->start()!=0

)152 tokenlist=list;

153if(!list->outtofile(tokenfile))

154 cerr<<"

error:cannot open the lexfile!

"<155if(!list->outtoscreen())

156 cerr<<"

error:cannot write on screen!

"<157return

list;

158159

}160 state scanner::thestate(char

ch)else

if(isdigit(ch))else

if(issymbol(ch))else

if(ch=='

else

if(ch=='

'||ch=='\t'

)else

if(ch=='

\n'||ch=='

\r')else

if(ch==eof)else

177return

s8;178

}179

bool scanner::isletter(char

ch)184

bool scanner::isdigit(char

ch)189

bool scanner::issymbol(char

ch)196

int scanner::getcode(const

char*ch)

201}

202return -1

;203

}204

int scanner::isreservedword(const

char*ch)

209}

210return -1

;211

}212

void scanner::inserttokenlist(list* list,tokennode*ptr)

213217

void scanner::isletterstr(file*fp,int linenum,list*list)

225if(ch!=eof)

226ungetnextchar(fp);

227int lex=isreservedword(str1.c_str());

228if(lex!=-1)//

c_str() 以 char* 形式傳回 str 內含字串

229else

236}

237238

void scanner::isnumstr(file*fp,int linenum,list*list)

246if(ch!=eof)

247ungetnextchar(fp);

248 tokennode *ptr;

249 ptr=new tokennode(linenum,intc,"

intc

",str2.c_str());

250inserttokenlist(list,ptr);

251}

252void scanner::issignstr(file*fp,int linenum,list*list)

265else

266ungetnextchar(fp);

267return

;268

}269

if(ch=='.'

) 270

278if(ch1!=eof)

279ungetnextchar(fp);

280 ptr=new tokennode(linenum,getcode("

."),"

dot","

程式結束符,無語義資訊");

281inserttokenlist(list,ptr);

282return

;283

}284

string

str;

285 str+=ch;

286 ptr=new tokennode(linenum,getcode(str.c_str()),word[getcode(str.c_str())],"

單分隔符,無語義資訊");

287inserttokenlist(list,ptr);

288}

289void scanner:: iscommentstr(file*fp,int

linenum) ')

295304 ch=getnextchar(fp);

305}

306307

}308

int scanner:: getlex(const

char *ch)

309315

return -1

;316 }

手工打造編譯器之詞法分析器3

逆波蘭表示式,可以去除括號 建立適合計算機處理的表示式,該表示式有正確的運算優先順序。正常的表示式 逆波蘭表示式 a b a,b,a b c a,b,c,a b c d a,b,c,d,a d b c a,d,b,c,a 1 3 a 1,3 運算的時候,遇到可以歸併的就歸併計算。如 5 4 3 2 ...

編譯器 詞法分析

總結 詞法分析 字串流 mov sum,x 執行加法運算 單詞流 mov sum,x 屬性字流 token type instr token type ident token type comma token type ident語法分析token currtoken getnexttoken 從屬...

編譯原理之詞法分析器(C C)

從乙個檔案中讀取原始碼,執行後可以直接看到結果,也可在指定檔案中檢視結果。這個詞法分析器只實現了部分關鍵字 字元等的識別,可在key陣列自行新增,種別碼的判別與新增用case更加方便,可寫下試試。include include include include include using namesp...