JFLex用戶手冊(cè)中文版_第1頁(yè)
JFLex用戶手冊(cè)中文版_第2頁(yè)
JFLex用戶手冊(cè)中文版_第3頁(yè)
JFLex用戶手冊(cè)中文版_第4頁(yè)
JFLex用戶手冊(cè)中文版_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、jflex詞法分析安裝與配置1. 下載jflex-1.4.3.zip,解壓縮到本地目錄(c:/jflex)。2. 找到j(luò)flexbinjflex.bat文件,配置java home和jflex home3. 把x:jflexbin寫入系統(tǒng)環(huán)境變量path中運(yùn)行可視化方式直接運(yùn)行jflexbinjflex.bat文件,打開(kāi)可視化界面操作即可。命令行方式配置把x:jflexbin以及x:jflexlib jflex.jar配置到系統(tǒng)環(huán)境變量的classpath中。格式j(luò)ava jflex.main 運(yùn)行參數(shù)-d 生成文件的輸出目錄-skel 使用外部的骨架文件生成掃描器類,它大多數(shù)情況下用于jfl

2、ex的維護(hù)和低級(jí)別定制。只有在你知道自己正在作什么時(shí)候才使用它。jflex的源碼中帶有一個(gè)骨架文件,預(yù)先編寫骨架文件才能使用此命令。-nomin在掃描器生成的過(guò)程中,跳過(guò)dfa簡(jiǎn)化步驟。-jlex完全兼容jlex-dot為nfa, dfa and minimised dfa生成擴(kuò)展名為.dot的graphviz圖型文件。該參數(shù)還在最初階段,尚未完全實(shí)現(xiàn)。-dump在控制臺(tái)顯示nfa轉(zhuǎn)換表,初始dfa和最簡(jiǎn)dfa。-verbose or v顯示生成過(guò)程信息。-quiet or q僅顯示生成錯(cuò)誤信息-time顯示代碼生成耗時(shí)信息(不十分精確)-version打印jflex版本號(hào)-info打印系統(tǒng)以

3、及jdk信息。-pack使用%pack代碼生成策略-table使用%table代碼生成策略-switch使用%switch代碼生成策略-help or -h打印幫助信息,解釋運(yùn)行參數(shù)以及jflex用法。jflex 配置文件編寫配置文件以.flex為擴(kuò)展名,整個(gè)文檔分為三個(gè)部分,使用%劃分1. 用戶代碼2. 選項(xiàng)與聲明3. 詞法規(guī)則形式形如:用戶代碼.%選項(xiàng)與聲明.%詞法規(guī)則.用戶代碼jflex直接將這部分代碼拷貝到生成詞法分析器java源文件中,通常在這里我們只定義一些類注釋信息以及package和import的引用。選項(xiàng)與聲明在這一部分,選項(xiàng)用來(lái)定制詞法分析器,聲明則是聲明一些能夠在第三部分

4、(詞法規(guī)則定義)使用的宏定義和詞法狀態(tài),其中宏大多由正則表達(dá)式定義。選項(xiàng)所有選項(xiàng)都要由一個(gè)“%”符號(hào)開(kāi)頭,下面來(lái)列舉一下所有的選項(xiàng):類選項(xiàng)和用戶代碼%class定義生成詞法分析器java文件的文件名,如果不定義該選項(xiàng),則默認(rèn)生成 ”yylex.java”。例子: %class myscanner%implements使得生成的詞法分析器類實(shí)現(xiàn)特定的接口,可以同時(shí)實(shí)現(xiàn)多個(gè)接口。例子: %implements interface1,interface2%extends 使得生成的詞法分析器類是某個(gè)類的子類,至多定義一個(gè)%extends選項(xiàng)。例子: %extends parentclass%publ

5、ic使得生成的類是public的,類似的還有%final和%abstract指令,他們分別生成的類是final和abstract類型的。例子: %public%apiprivate使得生成的類文件中,所有生成的方法和變量都變?yōu)閜rivate,只有該類的構(gòu)造方法和用戶自定代碼段除外。如果使用了%cup選項(xiàng),那么next_token方法也不會(huì)被設(shè)定為私有。這個(gè)方法如果沒(méi)有特殊情況不推薦使用。例子: % apiprivate%用戶代碼.% 類代碼指令其中用戶代碼將被直接復(fù)制到生成類文件中,在這里你可以定義自己的成員變量和方法。此規(guī)范描述中出現(xiàn)多個(gè)類代碼指令,那么jflex將根據(jù)這些類代碼指令出現(xiàn)的先

6、后順序?qū)⑺麄兤唇悠饋?lái)。例子: %public string name;public void test()system.out.println(“this is a test!”);%init初始化代碼%init 初始化代碼將被直接復(fù)制生成類的構(gòu)造函數(shù)中,我們可以在這里對(duì)類指令代碼中聲明的成員變量進(jìn)行初始化工作。同類代碼指令一樣,如果出現(xiàn)多個(gè)初始化指令定義,那么jflex將根據(jù)這些類代碼指令出現(xiàn)的先后順序?qū)⑺麄兤唇悠饋?lái)。例子: %initname=”benson”;%init%initthrow使得生成的類的構(gòu)造器方法拋出某種異常,也就說(shuō)當(dāng)我們實(shí)例化生成的詞法分析器時(shí)需要捕獲異常才可以。例子:

7、方式1: %initthrowexception1,exception2%initthrow方式2:%initthrow exception1, exception2%ctorarg 使得生成的類的構(gòu)造器方法,包含參數(shù),可以設(shè)置多個(gè)該選項(xiàng),那么參數(shù)會(huì)按順序排列。例子:%ctorarg string ss%scanerror 定義當(dāng)掃描出現(xiàn)錯(cuò)誤時(shí)拋出的具體異常。例子:%scannerror xxexception%buffer設(shè)置默認(rèn)掃描緩沖區(qū)大小,默認(rèn)是16384例子: %buffer 16388掃描函數(shù)設(shè)置%function用于設(shè)置詞法掃描函數(shù)的名稱,如果不設(shè)置該指令,那么默認(rèn)的詞法掃描函數(shù)

8、名稱為:yylex;注意該指令優(yōu)先于%cup指令,因?yàn)?cup指令設(shè)置后,默認(rèn)掃描函數(shù)被命名為:next token,也就是說(shuō)當(dāng)我們使用了%cup指令后,盡量就不要使用%function指令了。例子: %function myscanner%integer,%int這兩條指令都使掃描函數(shù)返回java語(yǔ)言中的int類型,在這種設(shè)置下文件結(jié)尾返回yyeof它是生成類 中的一個(gè)public static final int 的常量。例子: %interger%intwrap這條指令使掃描函數(shù)返回java語(yǔ)言中的integer類型,在這種設(shè)置下文件結(jié)尾缺省值是null.例子: %intwrap%typ

9、e這條指令用于設(shè)置掃描函數(shù)的返回類型,在這種設(shè)置下文件結(jié)尾缺省值是null.如果指定的類型不是java.lang.object的子類那么應(yīng)該使用%eofval指令或者eof來(lái)指定其他文件結(jié)束值。例子:%type myclasssymbol%yylexthrow可以使掃描函數(shù)聲明拋出異常,可以拋出多個(gè)異常。例子:%yylexthrowexception1,exception2%yylexthrow或者:%yylexthrow exception1, exception2掃描結(jié)束操作當(dāng)掃描函數(shù)掃描到文件結(jié)束時(shí)都有一個(gè)默認(rèn)的返回值,當(dāng)然在掃描到文件結(jié)束時(shí)你也可以定義一個(gè)具體的值被返回或者一段具體代碼

10、被執(zhí)行。%eofval用戶代碼%eofval其中用戶代碼部分直接被復(fù)制到掃描函數(shù)中,并且在每次文件結(jié)束時(shí)執(zhí)行。這個(gè)用戶代碼應(yīng)該返回表示文件結(jié)束的值。例子:%eofval return new mysymbol()(sym.eof, null); % eofval %eof用戶代碼.%eof其中用戶代碼遇到文件結(jié)束時(shí)只執(zhí)行一次,用戶代碼將被放到void yy do eof()方法中,并且不返回任何值。如果需要返回值應(yīng)該使用%eofval%eofval指令或者eof規(guī)則。如果出現(xiàn)多個(gè)該指令,則按照出現(xiàn)先后順序被連接在一起。例子:%eof system.out.println( +nlines+t+

11、nwords+t+nchars);%eof%eofthrow可以使函數(shù)void yy do eof()聲明拋出異常,可以拋出多個(gè)異常。例子:%eofthrowexception1,exception2%eofthrow或者%eofthrow exception1,exception2%eofclose這條指令使jflex在文件結(jié)束處關(guān)閉輸入流,代碼yyclose()被追加到方法void yy do eof()中,并且在這個(gè)方法throw子句中聲明java.io.ioexception。例子:%eofclose%eofclose false關(guān)閉%eofclose的影響。例子:%eofclose

12、false添加main主函數(shù)%debug在生成類中生成一個(gè)main方法,它從命令行獲得輸入文件名,然后對(duì)這個(gè)文件運(yùn)行語(yǔ)法分析器,并向java控制臺(tái)打印每個(gè)返回記號(hào)的信息,直到遇到文件結(jié)束。所輸出的信息包括:line,column號(hào)(如果設(shè)置了%line,%column),匹配文本,執(zhí)行動(dòng)作。例子:%debug%standalone在生成類中生成一個(gè)main方法,它從命令行獲得輸入文件名,然后對(duì)這個(gè)文件運(yùn)行語(yǔ)法分析器,掃描器的返回值將被忽略,任何不匹配的文本將被打印在java控制臺(tái)之上。應(yīng)該避免使用額外的標(biāo)記類,掃描方法將被聲明返回默認(rèn)的int類型。例子:%standalonecup 能力%cu

13、p該指令等同于以下指令集%implements java_cup.runtime.scanner%function next_token%type java_cup.runtime.symbol%eofvalreturn new java_cup.runtime.symbol(.eof);%eofval%eofclose%cupsym 使用在%cup指令之前,定義cup包含token生成類/接口的名字,默認(rèn)為sym.例子:%cupsym mysym%cupdebug在生成類中生成一個(gè)main方法,它從命令行獲得輸入文件名,然后對(duì)這個(gè)文件運(yùn)行語(yǔ)法分析器,打印行號(hào),列號(hào),匹配字符以及標(biāo)準(zhǔn)的返回的c

14、up symbol名稱。byacc/j 能力%byacc該指令等同于以下指令集%integer%eofvalreturn 0;%eofval%eofclose代碼生成算法以下這些選項(xiàng),將使得jflex產(chǎn)生詞匯分析代碼。當(dāng)沒(méi)有設(shè)置代碼產(chǎn)生選項(xiàng)時(shí),%pack是默認(rèn)被使用的。%switch使用%swith指令可以使jflex詞法分析器產(chǎn)生一個(gè)嵌套的開(kāi)關(guān)結(jié)構(gòu)的代碼。這個(gè)方法可以在保證良好運(yùn)行的前提下,對(duì)編譯.class文件數(shù)量更好的壓縮。如果你的掃描器有過(guò)多的狀態(tài)(大于200個(gè)),你就可以考慮使用%table或者%pack.如果狀態(tài)再多(大于300個(gè)),則可能java編譯時(shí)產(chǎn)生錯(cuò)誤代碼,以致于執(zhí)行錯(cuò)誤

15、代碼或者在java虛擬機(jī)檢測(cè)過(guò)程中產(chǎn)生java.lang.verifyerror異常。當(dāng)出現(xiàn)這種情況是將被強(qiáng)制使用%pack。%table%table指令將產(chǎn)生一個(gè)經(jīng)典的表格驅(qū)動(dòng)掃描器,將使用數(shù)組編碼dfa表格。jflex只進(jìn)行數(shù)量較小的表格壓縮。%packpack是默認(rèn)設(shè)置,使用一個(gè)或者多個(gè)字符串生成dfa裝配表。當(dāng)沒(méi)有使用代碼生成方法的具體規(guī)定時(shí)默認(rèn)使用。字符集%7bit支持字符集中0-127#字符,如果超出范圍將拋出arrayindexoutofboundsexception異常。%full,%8bit支持字符集中0-255#字符,如果超出范圍將拋出arrayindexoutofboun

16、dsexception異常。%unicode,%16bit支持字符集中0-65535#字符,使用該字符集不會(huì)出現(xiàn)運(yùn)行時(shí)的溢出現(xiàn)象。%caseless,%ignorecase對(duì)字符的大小寫忽略的設(shè)置。也就是說(shuō)字母a可以對(duì)a進(jìn)行匹配,也可以匹配字母a.行,列,字符設(shè)置%char字符計(jì)數(shù)器,yychar記錄從輸入開(kāi)始到當(dāng)前記號(hào)開(kāi)始出處字符數(shù)(從0開(kāi)始計(jì)數(shù))。%line行計(jì)數(shù)器,yyline記錄當(dāng)前行數(shù)%column列計(jì)數(shù)器,yycolumn記錄當(dāng)前列數(shù)=聲明狀態(tài)% states包含狀態(tài)-定義可能出現(xiàn)的詞法狀態(tài)% xstates排除狀態(tài)-需要排除的詞法狀態(tài)。示例說(shuō)明 %states a, b%xsta

17、tes c%expr1 yybegin(a); action expr2 action expr3 action expr4 action 解釋:1. 首先確認(rèn)a,b狀態(tài)是包含狀態(tài),c是排除狀態(tài),默認(rèn)狀態(tài)yyinitial總是隱式的不需要被聲明。2. expr1不存在狀態(tài)列表,他可以匹配任何狀態(tài),除了排除狀態(tài)c。狀態(tài)跳轉(zhuǎn)到狀態(tài)。3. expr2只能匹配yyinitial和狀態(tài)。4. expr3只能匹配狀態(tài)5. expr4能夠匹配,三個(gè)狀態(tài)6. 總而言之,包含狀態(tài)和排除狀態(tài)的只有在規(guī)則前沒(méi)有狀態(tài)列表時(shí)才體現(xiàn)出來(lái)。那些狀態(tài)列表為空的規(guī)則只能匹配除排除狀態(tài)以外的所有規(guī)則。宏定義宏定義規(guī)則:宏標(biāo)示符正

18、則表達(dá)式按照這種形式定義的宏標(biāo)識(shí)符可以再第三部分引用,右邊的正則表達(dá)式必須是合式,并且不能包含, / 或者 $等運(yùn)算符。詞法規(guī)則詞法規(guī)則部分包括一組正則表達(dá)式和動(dòng)作行為,也就是當(dāng)正則表達(dá)式匹配成功后要執(zhí)行的java代碼。語(yǔ)法了解bnf范式語(yǔ)法結(jié)構(gòu)使用bnf范式形式給出,所以我們先做一個(gè)簡(jiǎn)單了解。在雙引號(hào)中的字(word)代表著這些字符本身。而double_quote用來(lái)代表雙引號(hào)。在雙引號(hào)外的字(有可能有下劃線)代表著語(yǔ)法部分。 尖括號(hào)( )內(nèi)包含的為必選項(xiàng)。 方括號(hào)( )內(nèi)包含的為可選項(xiàng)。 大括號(hào)( )內(nèi)包含的為可重復(fù)0至無(wú)數(shù)次的項(xiàng)。 豎線( | )表示在其左右兩邊任選一項(xiàng),相當(dāng)于or的意思

19、。 := 是“被定義為”的意思。結(jié)構(gòu)定義lexicalrules := rule+rule := statelist regexp lookahead action| statelist action| stategroupstategroup := statelist rule+ statelist := lookahead := $ | / regexpaction := javacode | |regexp := regexp | regexp| regexp regexp/正則表達(dá)式連接運(yùn)算| ( regexp )| (!|) regexp /”匹配任何文本直到第一次匹配regexp|

20、 regexp (*|+|?)| regexp number , number /regexp重復(fù)次數(shù)| (character|character-character)* | predefinedclass| identifier | stringcharacter+ | characterpredefinedclass := :jletter:/java.lang.character.isjavaidentifierstart( )決定的字符類| :jletterdigit:/由java.lang.character.isjavaidentifierpart( )決定的字符類| :lette

21、r:/由java.lang.character.isletter( )決定的字符類| :digit:/由java.lang.character.isdigit( )決定的字符類| :uppercase:/由java.lang.character.isuppercase( )決定的字符類| :lowercase:/由java.lang.character.islowercase( )決定的字符類| ./包含除n 外的所有字符上述 ebnf 文法中使用了以下終結(jié)符:javacode:表示java 語(yǔ)言中的語(yǔ)句序列。number:表示一個(gè)非負(fù)的十進(jìn)制整數(shù)。identifier:表示一個(gè)標(biāo)識(shí)符,它是以

22、字母(用a-za-z表示)開(kāi)頭,后跟0 個(gè)或多個(gè)字母、數(shù)字或下劃線(即a-za-z0-9_)。轉(zhuǎn)義序列包括:n、r、t、f 和b;x 后跟兩個(gè)十六進(jìn)制數(shù)字(即a-fa-f0-9),或者反斜杠后跟從000 到377 的三個(gè)八進(jìn)制數(shù)字,表示標(biāo)準(zhǔn)的ascii 轉(zhuǎn)義序列;u 后跟四個(gè)十六進(jìn)制數(shù)字(即a-fa-f0-9),表示unicode 轉(zhuǎn)義序列;反斜杠后跟其他任何 unicode 字符,代表這個(gè)unicode 字符。character:是不包含下面字符之一的轉(zhuǎn)義序列或任何unicode 字符:| ( ) . * + ? $ / stringcharacter:是不包含下面字符之一的轉(zhuǎn)義序列或任何u

23、nicode 字符: 規(guī)則statelist 動(dòng)作代碼這條規(guī)則與%eofval 指令十分類似,其不同在于規(guī)則前可以放可選的statelist。在遇到文件結(jié)束并且詞法分析器當(dāng)前處于statelist 中的某一詞法狀態(tài)時(shí),執(zhí)行動(dòng)作代碼。語(yǔ)義character:匹配這個(gè)字符; (character | character - character)* :匹配任意一個(gè)出現(xiàn)在方括號(hào)內(nèi)的字符或者由字符范圍character - character 所界定的字符。例如,a0-2n可以匹配字符a、0、1、2 或者n。匹配空集,而不是空串。 (character | character - character)*

24、 :匹配所有未列在方括號(hào)中的字符。匹配任意字符。 stringcharacter+ :匹配包含在雙引號(hào)內(nèi)的文本。 identifier :匹配由名為identifier 的宏的rhs 所匹配的輸入。jflex 在正規(guī)式中使用以下標(biāo)準(zhǔn)運(yùn)算符(優(yōu)先級(jí)從高到低):一元后綴運(yùn)算符(*、+、?、n、n, m),假設(shè)a 是正規(guī)式,則a*-表示匹配 0 個(gè)或多個(gè)由a 匹配的輸入;a+-表示匹配 1 個(gè)或多個(gè)由a 匹配的輸入;a?-表示匹配 0 個(gè)或1 個(gè)由a 匹配的輸入;an-表示匹配 n 個(gè)由a 匹配的輸入;an, m-表示至少匹配 n 個(gè)、至多匹配m 個(gè)由a 匹配的輸入。一元前綴運(yùn)算符(!、),假設(shè)a

25、是正規(guī)式,則!a-表示匹配除a 所匹配的串之外的輸入;a-表示匹配任何文本直到第一次匹配a,它等價(jià)于正規(guī)式!(*a*)。連接(regexp := regexp regexp)聯(lián)合(regexp := regexp | regexp)正規(guī)式 r 前面加上運(yùn)算符,表示r 只在輸入流的每行開(kāi)始進(jìn)行匹配。正規(guī)式 r 后跟上$運(yùn)算符,表示r 只在輸入流的每行結(jié)尾進(jìn)行匹配。假設(shè) r1 和r2 是正規(guī)式,則r1/r2 表示r1 匹配的文本必須是定長(zhǎng)的,或者r2 的內(nèi)容的開(kāi)始不匹配r1 的尾部。例如,abc / a|b 是合法的,因?yàn)閍bc是定長(zhǎng)的;a|ab / x* 也是合法的,因?yàn)閤*的前綴不匹配a|ab

26、的后綴;x|xy / yx是非法的,因?yàn)閤|xy的后綴y也是yx的前綴。在動(dòng)作代碼中可以訪問(wèn)的應(yīng)用編程接口(api)生成的詞法分析器類中的方法和成員變量名以“yy”為前綴,表示它們是自動(dòng)生成的,避免與復(fù)制到這個(gè)類中的用戶代碼有名字沖突。由于用戶代碼也是類中的一部分,jflex 沒(méi)有像private 修飾符這樣的語(yǔ)言手段來(lái)指示哪些方法和成員是內(nèi)部的,哪些屬于應(yīng)用編程接口(api)。取而代之,jflex 遵循一種命名約定:以“zz”為名字前綴的方法或域?qū)⒈徽J(rèn)為是內(nèi)部使用的,在jflex 的各發(fā)布版本之間不會(huì)通告對(duì)這些方法或域的變化;生成類中不以“zz”為名字前綴的方法或域就屬于提供給用戶在動(dòng)作代碼

27、中使用的api,在jflex 的各發(fā)布版本之間會(huì)盡可能地支持它們并保持穩(wěn)定不變。api方法和域組成以下方法由jflex自動(dòng)生成,并且提供給用戶使用。string yytext()返回匹配的輸入文本串int yylength()返回所匹配的輸入文本串的長(zhǎng)度char yycharat(int pos)返回位于匹配的文本中第pos 個(gè)字符,這等價(jià)于yytext( ).charat(pos),但是執(zhí)行得會(huì)更快一些。pos 的取值范圍是0 到y(tǒng)ylength( )-1。void yyclose()關(guān)閉輸入流void yyreset(java.io.reader reader)關(guān)閉當(dāng)前的輸入流,并復(fù)位詞法分析器,使之讀取一個(gè)新的輸入流。所有的內(nèi)部變量將被復(fù)位,原先的輸入流不能被重用(內(nèi)部緩沖區(qū)的內(nèi)容被丟棄)。詞法狀態(tài)被設(shè)置為yy_initial。void yypushstream(java.io.reader reader)將當(dāng)前的輸入流保存到一個(gè)棧中,并從一個(gè)新的輸入流中讀取。詞法狀態(tài)以及行、字符和列的計(jì)數(shù)信息保持不變。可以用

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論