天天看點

《編譯與反編譯技術實戰 》一 1.2 詞法分析生成器LEX

本節書摘來自華章出版社《編譯與反編譯技術實戰 》一書中的第1章,第1.2節,龐建民 主編 ,劉曉楠 陶紅偉 嶽 峰 戴超 編著,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

詞法分析是編譯過程的第一個階段,其任務就是将輸入的各種符号轉化成相應的辨別符号,轉化後的辨別符很容易被後續階段處理。

lex是lexical compiler的縮寫,是unix環境下非常著名的工具,主要功能是生成一個詞法分析器的c源碼,描述規則采用正規表達式。描述詞法分析器的檔案*.l經過lex編譯後生成一個lex.yy.c的檔案,然後由c編譯器編譯生成一個詞法分析器。

lex接收使用者輸入的正規表達式,識别這些表達式并且将輸入流轉化為比對這些表達式的字元串。在這些字元串的分界處,使用者提供的程式片段被執行。lex代碼檔案将正規表達式和程式片段關聯,将每一條輸入對應到由lex生成的程式的表達式,且執行相應的代碼片段。

為了完成任務,除了需要提供比對的表達式以外,使用者還需要提供其他代碼,甚至是由其他生成器産生的代碼。使用者提供一般程式設計語言的代碼片段完成程式識别表達式後的工作。是以,使用者自由編寫動作代碼時,并不影響其編寫進階語言代碼來比對字元串表達式。這就避免迫使使用者使用字元串語言來進行輸入分析時,也必須使用同樣的方法來編寫字元處理程式,而這樣做有時是不合适的。lex不是完整的語言,它是一個新語言的生成器,可以插入各種不同的被叫作“宿主語言”的程式設計語言中。就像大多數進階語言可以生成在不同計算機硬體上運作的代碼一樣,lex可以生成不同的宿主語言。宿主語言用于lex生成輸出代碼,也用于使用者插入程式片段,這使得lex适用于不同的環境和不同的使用者。每一個應用程式可以是硬體、适用于該任務的宿主語言、使用者背景和局部接口屬性的直接結合。現在,lex唯一支援的宿主語言是c,過去也支援過其他語言。fortran lex自身一般運作于unix或linux系統之上,但是lex生成的代碼可以在任何适當的編譯器上使用。

lex将使用者輸入的表達式和動作代碼轉換為宿主語言,生成的函數一般名為yylex。yylex識别字元流中的表達式,并且當每一個表達式被檢測出來後,輸出相應的動作。

lex的檔案結構簡單,分為三個部分:

分别是聲明段、規則段和輔助部分。

2)規則段是由正規表達式和相應的動作組成的。如

值得注意的是,lex依次嘗試每一個規則,盡可能地比對最長的輸入流,即規則部分具有優先級的概念。比如下面的規則部分

對于内容“aaaaaaa”,lex程式會輸出“i like run”,首先比對最長的4個“a”,之後在剩下的三個“a”中比對兩個“a”,直到最後的一個“a”。可以看出lex的确按照最長的規則比對。

3)輔助部分放一些掃描器的其他子產品,可以包含用c語言編寫的子程式,而這些子程式可以用在前面的動作中,這樣就可以達到簡化程式設計的目的。輔助部分也可以在另一個程式檔案中編寫,最後再連結到一起。生成c代碼後,需用c的編譯器編譯,連結時需要指定連結庫。

本書的第3章将更加詳細地介紹lex及其用法。需要說明的是,對于gnu/linux使用者,與unix環境中lex對應的工具是flex,其具體用法和lex相似,這裡不再贅述。

繼續閱讀