資源描述:
《yacc 與 lex 快速入門》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、Yacc與Lex快速入門Lex與Yacc介紹AshishBansal(mailto:abansal@ieee.org?subject=Yacc與Lex快速入門&cc=abansal@ieee.org),軟件工程師,Sapient公司AshishBansal具有印度瓦臘納西BanarasHindu大學(xué)技術(shù)學(xué)院的電子與通信工程學(xué)士學(xué)位。他目前是Sapient公司的軟件工程師。他的Email是mailto:abansal@ieee.org?cc=abansal@ieee.org。簡介:?Lex和Yacc是UNI
2、X兩個非常重要的、功能強(qiáng)大的工具。事實上,如果你熟練掌握Lex和Yacc的話,它們的強(qiáng)大功能使創(chuàng)建FORTRAN和C的編譯器如同兒戲。AshishBansal為您詳細(xì)的討論了編寫自己的語言和編譯器所用到的這兩種工具,包括常規(guī)表達(dá)式、聲明、匹配模式、變量、Yacc語法和解析器代碼。最后,他解釋了怎樣把Lex和Yacc結(jié)合起來。標(biāo)記本文!Lex代表LexicalAnalyzar。Yacc代表YetAnotherCompilerCompiler。讓我們從Lex開始吧。LexLex是一種生成掃描器的工具。掃描器是
3、一種識別文本中的詞匯模式的程序。這些詞匯模式(或者常規(guī)表達(dá)式)在一種特殊的句子結(jié)構(gòu)中定義,這個我們一會兒就要討論。一種匹配的常規(guī)表達(dá)式可能會包含相關(guān)的動作。這一動作可能還包括返回一個標(biāo)記。當(dāng)Lex接收到文件或文本形式的輸入時,它試圖將文本與常規(guī)表達(dá)式進(jìn)行匹配。它一次讀入一個輸入字符,直到找到一個匹配的模式。如果能夠找到一個匹配的模式,Lex就執(zhí)行相關(guān)的動作(可能包括返回一個標(biāo)記)。另一方面,如果沒有可以匹配的常規(guī)表達(dá)式,將會停止進(jìn)一步的處理,Lex將顯示一個錯誤消息。Lex和C是強(qiáng)耦合的。一個.lex文件
4、(Lex文件具有.lex的擴(kuò)展名)通過lex公用程序來傳遞,并生成C的輸出文件。這些文件被編譯為詞法分析器的可執(zhí)行版本。Lex的常規(guī)表達(dá)式常規(guī)表達(dá)式是一種使用元語言的模式描述。表達(dá)式由符號組成。符號一般是字符和數(shù)字,但是Lex中還有一些具有特殊含義的其他標(biāo)記。下面兩個表格定義了Lex中使用的一些標(biāo)記并給出了幾個典型的例子。用Lex定義常規(guī)表達(dá)式字符含義A-Z,0-9,a-z構(gòu)成了部分模式的字符和數(shù)字。.匹配任意字符,除了。-用來指定范圍。例如:A-Z指從A到Z之間的所有字符。[]一個字符集合。匹配括號
5、內(nèi)的任意字符。如果第一個字符是^那么它表示否定模式。例如:[abC]匹配a,b,和C中的任何一個。*匹配0個或者多個上述的模式。+匹配1個或者多個上述模式。?匹配0個或1個上述模式。$作為模式的最后一個字符匹配一行的結(jié)尾。{}指出一個模式可能出現(xiàn)的次數(shù)。例如:A{1,3}表示A可能出現(xiàn)1次或3次。用來轉(zhuǎn)義元字符。同樣用來覆蓋字符在此表中定義的特殊意義,只取字符的本意。^否定。
6、表達(dá)式間的邏輯或。"<一些符號>"字符的字面含義。元字符具有。/向前匹配。如果在匹配的模版中的“/”后跟有后續(xù)表達(dá)式,只匹配模版
7、中“/”前面的部分。如:如果輸入A01,那么在模版A0/1中的A0是匹配的。()將一系列常規(guī)表達(dá)式分組。常規(guī)表達(dá)式舉例常規(guī)表達(dá)式含義joke[rs]匹配jokes或joker。A{1,2}shis+匹配AAshis,Ashis,AAshi,Ashi。(A[b-e])+匹配在A出現(xiàn)位置后跟隨的從b到e的所有字符中的0個或1個。Lex中的標(biāo)記聲明類似C中的變量名。每個標(biāo)記都有一個相關(guān)的表達(dá)式。(下表中給出了標(biāo)記和表達(dá)式的例子。)使用這個表中的例子,我們就可以編一個字?jǐn)?shù)統(tǒng)計的程序了。我們的第一個任務(wù)就是說明如何
8、聲明標(biāo)記。標(biāo)記聲明舉例標(biāo)記相關(guān)表達(dá)式含義數(shù)字(number)([0-9])+1個或多個數(shù)字字符(chars)[A-Za-z]任意字符空格(blank)""一個空格字(word)(chars)+1個或多個chars變量(variable)(字符)+(數(shù)字)*(字符)*(數(shù)字)*Lex編程Lex編程可以分為三步:1.以Lex可以理解的格式指定模式相關(guān)的動作。2.在這一文件上運行Lex,生成掃描器的C代碼。3.編譯和鏈接C代碼,生成可執(zhí)行的掃描器。注意:如果掃描器是用Yacc開發(fā)的解析器的一部分,只需要進(jìn)行第一
9、步和第二步。關(guān)于這一特殊問題的幫助請閱讀Yacc和將Lex和Yacc結(jié)合起來部分?,F(xiàn)在讓我們來看一看Lex可以理解的程序格式。一個Lex程序分為三個段:第一段是C和Lex的全局聲明,第二段包括模式(C代碼),第三段是補(bǔ)充的C函數(shù)。例如,第三段中一般都有main()函數(shù)。這些段以%%來分界。那么,回到字?jǐn)?shù)統(tǒng)計的Lex程序,讓我們看一下程序不同段的構(gòu)成。C和Lex的全局聲明這一段中我們可以增加C變量聲明。這里我們將為字?jǐn)?shù)統(tǒng)計程序聲