編譯課程設(shè)計(jì)報(bào)告書(shū)_第1頁(yè)
編譯課程設(shè)計(jì)報(bào)告書(shū)_第2頁(yè)
編譯課程設(shè)計(jì)報(bào)告書(shū)_第3頁(yè)
編譯課程設(shè)計(jì)報(bào)告書(shū)_第4頁(yè)
編譯課程設(shè)計(jì)報(bào)告書(shū)_第5頁(yè)
已閱讀5頁(yè),還剩23頁(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、精選優(yōu)質(zhì)文檔-傾情為你奉上課程設(shè)計(jì)報(bào)告( 2014 - 2015年度第 1 學(xué)期)名 稱(chēng): 編譯技術(shù)課程設(shè)計(jì)B 題 目: 詞法分析器設(shè)計(jì) 算符優(yōu)先分析程序設(shè)計(jì) 基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯程序設(shè)計(jì) 院 系: * 班 級(jí): * 學(xué) 號(hào): * 學(xué)生姓名: * 指導(dǎo)教師: 編譯課程教學(xué)組 設(shè)計(jì)周數(shù): 1周 成 績(jī): 日期:2015年 1月 9日一、課程設(shè)計(jì)的目的與要求1 詞法分析器設(shè)計(jì)的目的與要求11 詞法分析器設(shè)計(jì)的目的本實(shí)驗(yàn)是為計(jì)算機(jī)科學(xué)與技術(shù)專(zhuān)業(yè)、網(wǎng)絡(luò)工程專(zhuān)業(yè)、信息安全專(zhuān)業(yè)的學(xué)生在學(xué)習(xí)編譯技術(shù)課程后,為加深對(duì)課堂教學(xué)內(nèi)容的理解,培養(yǎng)解決實(shí)際問(wèn)題能力而設(shè)置的實(shí)踐環(huán)節(jié)。通過(guò)這個(gè)實(shí)驗(yàn),使學(xué)生應(yīng)

2、用編譯程序設(shè)計(jì)的原理和技術(shù)設(shè)計(jì)出詞法分析器,了解掃描器的組成結(jié)構(gòu),不同種類(lèi)單詞的識(shí)別方法。能使得學(xué)生在設(shè)計(jì)和調(diào)試編譯程序的能力方面有所提高。為將來(lái)設(shè)計(jì)、分析編譯程序打下良好的基礎(chǔ)。12 詞法分析器設(shè)計(jì)的要求設(shè)計(jì)一個(gè)掃描器,該掃描器是一個(gè)子程序,其輸入是源程序字符串,每調(diào)用一次識(shí)別并輸出一個(gè)單詞符號(hào)。為了避免超前搜索,提高運(yùn)行效率,簡(jiǎn)化掃描器的設(shè)計(jì),假設(shè)該程序設(shè)計(jì)語(yǔ)言中,基本字(也稱(chēng)關(guān)鍵詞)不能做一般標(biāo)識(shí)符用,如果基本字、標(biāo)識(shí)符和常數(shù)之間沒(méi)有確定的運(yùn)算符或界符作間隔,則用空白作間隔。單詞符號(hào)及其內(nèi)部表示如表1-1所示,單詞符號(hào)中標(biāo)識(shí)符由一個(gè)字母后跟多個(gè)字母、數(shù)字組成,常數(shù)由多個(gè)十進(jìn)制數(shù)字組成。單

3、詞符號(hào)的內(nèi)部表示,即單詞的輸出形式為二元式:(種別編碼,單詞的屬性值)。表1-1單詞符號(hào)及其內(nèi)部表示單詞符號(hào)種別編碼單詞的屬性值BEGINIFTHENELSEEND標(biāo)識(shí)符整型常數(shù)+*()123456789101112在名字表中的地址十進(jìn)制整數(shù)2 算符優(yōu)先分析程序設(shè)計(jì)的目的與要求2.1 算符優(yōu)先分析程序設(shè)計(jì)的目的本實(shí)驗(yàn)是為計(jì)算機(jī)科學(xué)與技術(shù)等專(zhuān)業(yè)的學(xué)生在學(xué)習(xí)編譯技術(shù)課程后,為加深對(duì)課堂教學(xué)內(nèi)容的理解,培養(yǎng)解決實(shí)際問(wèn)題能力而設(shè)置的實(shí)踐環(huán)節(jié)。通過(guò)這個(gè)實(shí)驗(yàn),使學(xué)生應(yīng)用編譯程序設(shè)計(jì)的原理和技術(shù), 設(shè)計(jì)、編寫(xiě)和調(diào)試算符優(yōu)先分析程序,了解算符優(yōu)先分析程序的組成結(jié)構(gòu),掌握實(shí)現(xiàn)通用算符優(yōu)先分析算法的方法。能使得學(xué)

4、生在設(shè)計(jì)和調(diào)試編譯程序的能力方面有所提高。為將來(lái)設(shè)計(jì)、分析編譯程序打下良好的基礎(chǔ)。2.2 算符優(yōu)先分析程序設(shè)計(jì)的要求算符優(yōu)先分析屬于自下而上的分析方法,該語(yǔ)法分析程序的輸入是終結(jié)符號(hào)串(即單詞符號(hào)串,以一個(gè)“”結(jié)尾),如果輸入串是句子則輸出“YES”,否則輸出“NO”和錯(cuò)誤信息。算符優(yōu)先分析過(guò)程與非終結(jié)符號(hào)無(wú)關(guān),當(dāng)由文法產(chǎn)生了優(yōu)先關(guān)系之后文法也就失去了作用,本題目給出文法的目的是為了便于對(duì)語(yǔ)法分析結(jié)果進(jìn)行驗(yàn)證。(1)文法設(shè)算符優(yōu)先文法為: 說(shuō)明:i為整型常數(shù)或者為標(biāo)識(shí)符表示整型變量;使用中用*表示。(2)優(yōu)先關(guān)系表設(shè)優(yōu)先關(guān)系表如表1-2所示。表1-2優(yōu)先關(guān)系表+ * i ( ) # + * i

5、 ( ) # 3 基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯程序的設(shè)計(jì)的目的和要求3.1 基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯程序的設(shè)計(jì)的目的本實(shí)驗(yàn)是為計(jì)算機(jī)科學(xué)與技術(shù)等專(zhuān)業(yè)的學(xué)生在學(xué)習(xí)編譯技術(shù)課程后,為加深對(duì)課堂教學(xué)內(nèi)容的理解,培養(yǎng)解決實(shí)際問(wèn)題能力而設(shè)置的實(shí)踐環(huán)節(jié)。通過(guò)這個(gè)實(shí)驗(yàn),使學(xué)生應(yīng)用編譯程序設(shè)計(jì)的原理和技術(shù), 通過(guò)設(shè)計(jì)、編寫(xiě)和調(diào)試語(yǔ)法制導(dǎo)翻譯程序,掌握從一種語(yǔ)句的語(yǔ)法和語(yǔ)義出發(fā),構(gòu)造相應(yīng)的語(yǔ)義子程序,實(shí)現(xiàn)基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯的方法。能使得學(xué)生在設(shè)計(jì)和調(diào)試編譯程序的能力方面有所提高。為將來(lái)設(shè)計(jì)、分析編譯程序打下良好的基礎(chǔ)。3.2 基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯程序的設(shè)計(jì)的要求算符

6、優(yōu)先分析方法是通過(guò)反復(fù)把輸入符號(hào)移進(jìn)分析棧,使用優(yōu)先關(guān)系表在分析棧頂尋找最左素短語(yǔ),將其歸約為一個(gè)非終結(jié)符號(hào)而實(shí)現(xiàn)的。這個(gè)分析過(guò)程與非終結(jié)符號(hào)無(wú)關(guān),當(dāng)由文法產(chǎn)生了優(yōu)先關(guān)系之后文法也就失去了作用(所以本題目無(wú)需給出文法)?;谒惴麅?yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯是在算符優(yōu)先語(yǔ)法分析的基礎(chǔ)上進(jìn)行翻譯工作(即語(yǔ)義分析),每當(dāng)將一個(gè)最左素短語(yǔ)歸約為一個(gè)非終結(jié)符號(hào)時(shí),就調(diào)用對(duì)應(yīng)產(chǎn)生式的語(yǔ)義子程序,去完成相應(yīng)的語(yǔ)義翻譯工作,這步歸約使用的產(chǎn)生式對(duì)非終結(jié)符號(hào)不加區(qū)分(即將所有的非終結(jié)符號(hào)用一個(gè)通用的非終結(jié)符號(hào)表示)。語(yǔ)法制導(dǎo)翻譯程序的輸入是終結(jié)符號(hào)串(即單詞符號(hào)串,以一個(gè)“”結(jié)尾),如果輸入符號(hào)串是句子,則按照其

7、語(yǔ)義進(jìn)行翻譯,輸出等價(jià)的四元式序列(作為練習(xí)應(yīng)顯示輸出)。二、課程設(shè)計(jì)正文1 詞法分析器設(shè)計(jì)1.1 程序的實(shí)現(xiàn)流程(1) 輸出提示;(2) 讀入源串;(3) 使用循環(huán)逐字符檢測(cè):如果該首字符是字母,則它是一個(gè)標(biāo)識(shí)符或關(guān)鍵字,開(kāi)始標(biāo)記;如果首字符是數(shù)字,在后面沒(méi)有字母,則它是數(shù)字,有字母則是標(biāo)識(shí)符,開(kāi)始標(biāo)記;如果是空格或者運(yùn)算符則終止這次標(biāo)記;(4) 每次終止標(biāo)記前都要輸出前面的關(guān)鍵字、標(biāo)識(shí)符或數(shù)字,然后輸出該運(yùn)算符,都以二元式形式輸出;(5) 檢索完最后一個(gè)字符或者遇到非法輸入則終止檢索。1.2自行規(guī)定(1) 關(guān)鍵字:begin,if,then,else,end;(2) 標(biāo)識(shí)符:以字母開(kāi)頭由字

8、母或數(shù)字組成并且不屬于關(guān)鍵字的單詞;(3) 數(shù)字:完全由十進(jìn)制數(shù)字組成;(4) 標(biāo)識(shí)符:+,*,*,(,)。1.3在屏幕上顯示begin:(1,-)if:(2,-)then:(3,-)else:(4,-)end:(5,-)標(biāo)識(shí)符:(6,在名字表中的地址)整型常數(shù):(7,十進(jìn)制整數(shù))+:(8,-)*:(9,-)*:(10,-)(:(11,-):(12,-)1.4程序流程圖開(kāi)始輸入字符串取一個(gè)字符是*嗎?是否指針A指向該字符是標(biāo)識(shí)符的第一個(gè)字符嗎?不是指針A指向該字符是a-z嗎? 是 是 是是數(shù)字的第一個(gè)字符? 還在數(shù)字中 輸出A到B字符串所對(duì)應(yīng)的二元式是0-9? 否 是 在標(biāo)識(shí)符中是空格? 否

9、是運(yùn)算符嗎?返回 否 是 數(shù)字中出現(xiàn)字母 是 否指針B指向該字符輸入錯(cuò)誤,存在非法字符輸出A到B字符串所對(duì)應(yīng)的二元式返回輸出該運(yùn)算符對(duì)應(yīng)的二元式2 算符優(yōu)先分析程序設(shè)計(jì)2.1自行規(guī)定可識(shí)別字符:i,+,*,(,),#,/。由于*識(shí)別起來(lái)有點(diǎn)兒麻煩,又限于時(shí)間上的問(wèn)題,我暫時(shí)用/表示的。2.2優(yōu)先級(jí)設(shè)計(jì)使用整形二維數(shù)組即鄰接矩陣形式存放,其中1為高于,0為等于,-1為低于,-2為不能比較。2.3程序流程這里用文字描述,具體流程圖參考語(yǔ)法制導(dǎo)翻譯。(1) 提示輸入;(2) 輸入字符串;(3) 錯(cuò)誤檢驗(yàn):主要進(jìn)行檢測(cè)輸入串中是否含有不能識(shí)別的字符,首字符必須是i或(,字符串內(nèi)部(后面只能是i;(4)

10、 輸入串放到緩沖區(qū)中,棧中只放#;(5) 當(dāng)棧中出現(xiàn)#N,緩沖區(qū)中出現(xiàn)#時(shí)退出;(6) 找到棧中第一個(gè)終結(jié)符,用top指向他;(7) 比較棧頂首終結(jié)符和緩沖區(qū)首字符的優(yōu)先級(jí):低于等于則入棧,高于就找到從棧頂數(shù)第二終結(jié)符準(zhǔn)備歸約,不能比較就輸出錯(cuò)誤并終止;(8) 歸約時(shí),如果棧頂首終結(jié)符和第二終結(jié)符優(yōu)先級(jí)相等就把他們及之間的字符歸約為N,如果棧頂首終結(jié)符優(yōu)先級(jí)高并且是棧頂字符則將該字符歸約為N,如果棧頂首終結(jié)符優(yōu)先級(jí)高并且棧頂字符是N則將該字符及其左右的N一起歸約為N。3 基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯程序的設(shè)計(jì)3.1在算符優(yōu)先分析程序的基礎(chǔ)上繼續(xù)實(shí)現(xiàn),可以輸出四元式。3.2為了實(shí)現(xiàn)輸出四元

11、式,需要找到兩個(gè)操作數(shù),即通過(guò)運(yùn)算符兩邊的N來(lái)找到被歸約為N的兩個(gè)操作數(shù)。我使用一個(gè)字符串?dāng)?shù)組來(lái)存放被歸約為N的操作數(shù),由于棧的特殊性質(zhì),每次歸約時(shí)都是從棧頂?shù)腘開(kāi)始,不論歸約的字符串中有幾個(gè)N都是從棧頂開(kāi)始,所以我想了一個(gè)方法:因?yàn)檩敵鏊脑綍r(shí)都是歸約運(yùn)算符和他兩邊的N,所以從第一個(gè)N開(kāi)始就記錄該N所對(duì)應(yīng)的字符串,以后每次歸約時(shí)都要找到該字符前面N的個(gè)數(shù),將被歸約的幾個(gè)字符以字符串形式一起存入對(duì)應(yīng)數(shù)組中,這樣再去找N對(duì)應(yīng)的歸約字符串就是他的操作數(shù)。3.3程序流程圖由于用電腦畫(huà)程序流程圖時(shí)一頁(yè)總是會(huì)不夠,所以我決定在紙上手工畫(huà)。3、 課程設(shè)計(jì)總結(jié)或結(jié)論三個(gè)程序均為自己寫(xiě)的,使用Java語(yǔ)言,E

12、clipse集成開(kāi)發(fā)環(huán)境實(shí)現(xiàn)。1詞法分析器設(shè)計(jì)1.1為了實(shí)現(xiàn)字符串的增加與刪除,我使用的是StringBuilder,他是繼承字CharSequence,是一個(gè)16位字符數(shù)組,以至于在后面拿StringBuilder對(duì)象和String對(duì)象進(jìn)行匹配時(shí)出現(xiàn)錯(cuò)誤。因?yàn)橐粋€(gè)是字符數(shù)組,一個(gè)是字符串,必須轉(zhuǎn)化為相同形式才可以比較,我查閱JDK的幫助文檔發(fā)現(xiàn)String類(lèi)中有一個(gè)將字符串轉(zhuǎn)化為字符數(shù)組的方法toCharInt(),但是轉(zhuǎn)化后并不是16位的,于是我自己嘗試著寫(xiě)了一個(gè)轉(zhuǎn)化函數(shù)toCharInt16(),結(jié)果發(fā)現(xiàn)還是不能匹配成功,通過(guò)調(diào)試發(fā)現(xiàn)兩方都是16位字符數(shù)組但就是不能匹配成功,我嘗試將eq

13、uals()換位=,還是不行。后面突然發(fā)現(xiàn),我可以將這個(gè)StringBuilder對(duì)象轉(zhuǎn)化為String對(duì)象,總類(lèi)Object中有toString(),這個(gè)方法我經(jīng)常用,但是一直想著將字符串轉(zhuǎn)換,而忽略了其它。1.2實(shí)現(xiàn)技術(shù)需要分析的種類(lèi)比較多:begin,if,then,else,end是關(guān)鍵字不是標(biāo)識(shí)符需要單獨(dú)考慮,同時(shí)他們屬于字符串,可以通過(guò)找到標(biāo)識(shí)符后再判斷是不是關(guān)鍵字;我使用了兩個(gè)標(biāo)志位來(lái)記錄并判斷標(biāo)識(shí)符和數(shù)字,flagL判斷是不是在標(biāo)識(shí)符中,flagN判斷是不是在數(shù)字中。如果該字符是標(biāo)識(shí)符,flagL為false那么這個(gè)字符是接下來(lái)這個(gè)標(biāo)識(shí)符的第一個(gè)字母,這時(shí)就可以用指針point

14、A指向他,并把flagL置為true,flagL為true那么直接去檢測(cè)下一個(gè)字符;如果該字符是數(shù)字,flagL為false并且flagN為false說(shuō)明他是數(shù)字的第一個(gè)字母,這時(shí)可以用pointA指向他,并把flagN置為true,flagL為false并且flagN為true說(shuō)明這個(gè)字母仍然處于數(shù)字中,可以直接去檢測(cè)下一個(gè)字符,flagL為true并且flagN為false說(shuō)明這個(gè)字母正處在一個(gè)標(biāo)識(shí)符中,可以直接去檢測(cè)下一個(gè)字符,其它情況即flagL為true并且flagN為true說(shuō)明這個(gè)字母既在標(biāo)識(shí)符中又在數(shù)字中,是不可能發(fā)生的。對(duì)于運(yùn)算符來(lái)說(shuō),+,*,(,)都是一個(gè)字符,檢測(cè)到是他們

15、就可以置pointB的值,讓從pointA開(kāi)始到pointB-1的字符作為一個(gè)整體來(lái)說(shuō),為了區(qū)分他們是標(biāo)識(shí)符還是數(shù)字,因?yàn)闃?biāo)志符和數(shù)字的屬性值不同,這是可以檢測(cè)他的第一個(gè)字符,這個(gè)字符是字母這個(gè)整體就是標(biāo)識(shí)符或關(guān)鍵字,這個(gè)字符是數(shù)字這個(gè)整體就是數(shù)字,他們輸出時(shí)有區(qū)別;我們還有一個(gè)運(yùn)算符*,由于他有兩個(gè)字符,需要區(qū)別對(duì)待,當(dāng)檢測(cè)到第一個(gè)*時(shí)要先檢測(cè)下一個(gè)字符是不是*,如果是說(shuō)明檢測(cè)到的是*,這樣下一次循環(huán)檢測(cè)就沒(méi)有意義了,我又用了一個(gè)標(biāo)志位isDoubleAsterisk,默認(rèn)是false的,這時(shí)就可以將其置為true,每次循環(huán)時(shí)首先檢測(cè)isDoubleAsterisk是否為true,為true

16、就直接進(jìn)入下一循環(huán)。將他們前面的整體輸出為二元式后要將以上三個(gè)標(biāo)志位置為false,然后還要將他們自己的二元式輸出。檢測(cè)到是空格就直接將前面整體的二元式輸出。1.3存在不足由于時(shí)間上的關(guān)系,這個(gè)小程序存在一些bug,比如連續(xù)兩個(gè)空格,就會(huì)輸出兩次前面的東西,雖然不同但是對(duì)整體結(jié)果有影響;輸完最后一個(gè)字符后必須要輸入個(gè)空格才能把最后這個(gè)輸出。2 算符優(yōu)先分析程序設(shè)計(jì)2.1使用一個(gè)StringBuilder對(duì)象stack作為棧,初始值為#;使用一個(gè)StringBuilder對(duì)象buffer作為緩沖區(qū),初始值為輸入的源串。2.2由于循環(huán)次數(shù)是不確定的,我使用一個(gè)do-while語(yǔ)句來(lái)不斷循環(huán),并設(shè)置

17、一個(gè)標(biāo)志位flag來(lái)判斷是否可以再次執(zhí)行。flag被置為false即不能再循環(huán)的情況有:開(kāi)始時(shí)判斷包含非法字符;存不合適的搭配,比如(之后必須是i;兩個(gè)字符的優(yōu)先級(jí)不能比較。2.3為了輸出能夠?qū)R,我使用了水平制表符即“t”。2.4使用了兩個(gè)指針指向從棧頂數(shù)第一個(gè)終結(jié)符和第二個(gè)終結(jié)符,第一個(gè)為全局變量,第二個(gè)為局部變量。2.5規(guī)約時(shí)分了三種情況:被歸約的是棧頂?shù)哪莻€(gè)字符;被歸約的是該字符和他兩邊的N;被歸約的是該字符以及他前面的N還有他前面與他同優(yōu)先級(jí)的字符。在程序中歸約只是字符串的變換。2.6仍有不足,我將*換成了/,這樣減小了難度。由于時(shí)間上的關(guān)系,沒(méi)有想到解決的辦法。3基于算符優(yōu)先分析方

18、法的語(yǔ)法制導(dǎo)翻譯程序的設(shè)計(jì)3.1他是在第二個(gè)實(shí)驗(yàn)的基礎(chǔ)上實(shí)現(xiàn)的,時(shí)間上本來(lái)可以減少的,但是出現(xiàn)了一個(gè)比較難解決的問(wèn)題:如何通過(guò)N來(lái)找到這個(gè)N被歸約之前是什么。因?yàn)槌绦蛑蠳就是一個(gè)字符,所有的N都一樣,這就出現(xiàn)了難題。我想到的第一種方法是使用ArrayList創(chuàng)建兩個(gè)動(dòng)態(tài)數(shù)組,一個(gè)用來(lái)存放Nn,這時(shí)需要把棧中歸約成的N變?yōu)橛袠?biāo)記的Nn,然后用另一個(gè)動(dòng)態(tài)數(shù)組作為這個(gè)的映射,保存該N被歸約前的東西。但是有兩個(gè)問(wèn)題:(1)棧中不再是N了,與我們所學(xué)的有些差距;(2)原來(lái)的N是一個(gè)字符,現(xiàn)在的Nn是兩個(gè),檢測(cè)時(shí)肯定不容易。我果斷放棄了這種方法。第二種方法是每一次歸約時(shí)都去檢測(cè)一下棧,從棧底開(kāi)始找這個(gè)字符

19、前面有幾個(gè)N,這個(gè)整數(shù)作為索引,放將要被歸約的東西的進(jìn)一個(gè)字符串?dāng)?shù)組中。如果剛剛把四元式輸出了,說(shuō)明有了一個(gè)新的結(jié)果,使用Tn表示的,這里也應(yīng)該要?dú)w約并且會(huì)將兩個(gè)N歸約掉,所以需要將這個(gè)Tn放到前一個(gè)N的數(shù)組中替換原來(lái)的內(nèi)容。我其實(shí)對(duì)第二種方法沒(méi)有多少信心,感覺(jué)也上可能對(duì),但是經(jīng)過(guò)試驗(yàn)后發(fā)現(xiàn)是對(duì)的。我就又回過(guò)頭去想為什么這么做可以,發(fā)現(xiàn)因?yàn)樵谶@個(gè)棧中,被歸約的都是從棧頂開(kāi)始的N,不會(huì)只將中間的N和其它字符歸約掉,這樣就保證了歸約的是棧頂首終結(jié)符。3.2另一個(gè)遇到的問(wèn)題就相對(duì)來(lái)說(shuō)簡(jiǎn)單了,就是在什么時(shí)候什么位置輸出四元式。自己在紙上寫(xiě)了幾個(gè)語(yǔ)句的四元式以及算符優(yōu)先分析的過(guò)程,發(fā)現(xiàn)在歸約運(yùn)算符時(shí)會(huì)連

20、帶其兩邊的N一起歸約,這兩個(gè)N原來(lái)的值就是四元式的兩個(gè)操作數(shù)。附錄(設(shè)計(jì)流程圖、程序、運(yùn)行結(jié)果等)實(shí)驗(yàn)一源代碼:import java.util.*;/* * author SXH * 說(shuō)明 詞法分析器 * */public class LexicalAnalysis /* * 存儲(chǔ)源代碼 * */static String sourceCode;/* * 兩個(gè)指針 * */static int pointA = 0, pointB = 0;/* * 當(dāng)前字符 * */static char presentChar;/* * 存放每次識(shí)別的單詞 * */static StringBuilder

21、 temp = new StringBuilder("");/* * 是否處于單詞中 */static boolean flagL = false;/* * 是否處于數(shù)字中 * */static boolean flagN = false;/* * 是否是雙星號(hào)即“*” * */static boolean isDoubleAsterisk = false;/* * 詞法分析 */public static void main(String args) System.out.println("單詞符號(hào)tt種別編碼tt單詞屬性");System.out.p

22、rintln("begintt 1tt -");System.out.println("iftt 2tt -");System.out.println("thentt 3tt -");System.out.println("elsett 4tt -");System.out.println("endtt 5tt -");System.out.println("標(biāo)識(shí)符tt 6tt在名字表中的地址");System.out.println("整型常數(shù)tt 7tt十進(jìn)制整

23、數(shù)");System.out.println("+tt 8tt -");System.out.println("*tt 9tt -");System.out.println("*tt 10tt -");System.out.println("(tt 11tt -");System.out.println(")tt 12tt -");System.out.println("*");System.out.println(" 將以二元式形式輸出:(種別編碼,屬性

24、值)");Scanner s = new Scanner(System.in);System.out.print("請(qǐng)輸入:");sourceCode = s.nextLine();lexicalAnalysis(sourceCode);/* * 詞法分析 * * param sourceCode * 需要分析的字符串 * */static void lexicalAnalysis(String sourceCode) for (int i = 0; i < sourceCode.length(); i+) if (isDoubleAsterisk) / 是

25、連續(xù)的兩個(gè)*,去檢測(cè)下一個(gè)字符isDoubleAsterisk = false;continue; else presentChar = sourceCode.charAt(i);if (sourceCode.charAt(i) >= 'a' && sourceCode.charAt(i) <= 'z') / 如果是字母if (flagL = false) / 標(biāo)識(shí)符的第一個(gè)字符pointA = i;flagL = true; else / 仍然處于標(biāo)識(shí)符中continue; else if (sourceCode.charAt(i)

26、 >= '0'&& sourceCode.charAt(i) <= '9') / 如果是數(shù)字if (flagN = false && flagL = false) / 數(shù)字的第一個(gè)字符,他一定是數(shù)字pointA = i;flagN = true; else if (flagL = false && flagN = true) / 仍然處于數(shù)字中 else if (flagL = true && flagN = false) / 雖是數(shù)字,但他處于標(biāo)識(shí)符中 else / 數(shù)字中出現(xiàn)了字符,

27、錯(cuò)誤!System.err.println("數(shù)字中出現(xiàn)了字符,錯(cuò)誤!");return;continue; else if (sourceCode.charAt(i) = '+'| sourceCode.charAt(i) = '*'| sourceCode.charAt(i) = '('| sourceCode.charAt(i) = ')') / 是其它幾個(gè)字符pointB = i;switch (sourceCode.charAt(i) case '+':display();System

28、.out.println("(8,-)");break;case '*':if (sourceCode.charAt(i + 1) = '*') System.out.println("(10,-)");isDoubleAsterisk = true;/ i+; else display();System.out.println("(9,-)");break;case '(':System.out.println("(11,-)");break;case ')

29、':display();System.out.println("(12,-)");break; else if (sourceCode.charAt(i) = ' ') pointB = i;display(); else /輸入了不能識(shí)別的字符System.err.println("輸入了不能檢測(cè)的字符:" + sourceCode.charAt(i);return;/* * 顯示標(biāo)識(shí)符 * */static void letter() / temp.append(sourceCode.charAt(presentChar);S

30、ystem.out.println("(6," + (pointA + 1) + ")");temp = new StringBuilder();return;/* * 顯示數(shù)字 * */static void number() / temp.append(sourceCode.charAt(presentChar);System.out.println("(7," + temp + ")");temp = new StringBuilder();return;/* * 顯示其他字符,但是沒(méi)有用上 * */stat

31、ic void other() temp.append(sourceCode.charAt(presentChar);return;/* * 將數(shù)字、標(biāo)識(shí)符、關(guān)鍵字輸出 * */static void display() flagL = false;flagN = false;temp.append(sourceCode, pointA, pointB);if (temp.charAt(0) >= '0' && temp.charAt(0) <= '9') / 以數(shù)字開(kāi)頭一定是數(shù)字number(); else if (temp.cha

32、rAt(0) >= 'a' && temp.charAt(0) <= 'z') / 以字母開(kāi)頭是標(biāo)識(shí)符或關(guān)鍵字if (temp.toString().equals("begin") System.out.println("(1,-)"); else if (temp.toString().equals("if") System.out.println("(2,-)"); else if (temp.toString().equals("then&

33、quot;) System.out.println("(3,-)"); else if (temp.toString().equals("else") System.out.println("(4,-)"); else if (temp.toString().equals("end") System.out.println("(5,-)"); else letter();/* * 本來(lái)打算寫(xiě)一個(gè)將字符串轉(zhuǎn)化為16位字符數(shù)組的函數(shù),結(jié)果還是不能匹配,沒(méi)有使用 * */static char toC

34、harArray16(String string) char array = new char16;for (int j = 0; j < array.length; j+) if (j < string.length()arrayj = string.charAt(j);else arrayj = ' 'return array;實(shí)驗(yàn)一運(yùn)行結(jié)果:實(shí)驗(yàn)二源代碼:import java.util.*;/* * author SXH * 說(shuō)明 算符優(yōu)先分析 * */public class OperatorPrecedence /* * 源串 * */static St

35、ring resourceCode;/* * 判斷是否可以繼續(xù)執(zhí)行 */static boolean flag = true;/* * 棧 * */static StringBuilder stack = new StringBuilder("#");/* * 輸入緩沖區(qū) * */static StringBuilder buffer = new StringBuilder();/* * 步驟 */static int step = 1;/* * 棧頂?shù)谝粋€(gè)終結(jié)符 */static int top;/* * 字符順序表 *暫時(shí)用/表示 */static String seq

36、uenceList = "+*/i()#"/* * 優(yōu)先關(guān)系表,其中1為高于,0為等于,-1為低于,-2為不能比 */static int relation = 1, -1, -1, -1, -1, 1, 1 , 1, 1, -1, -1, -1, 1, 1 , 1, 1, -1, -1, -1, 1, 1 , 1, 1, 1, -2, -2, 1, 1 , -1, -1, -1, -1, -1, 0, -2 , 1, 1, 1, -2, -2, 1, 1 , -1, -1, -1, -1, -1, -2, 0 ;/* * 主程序 */public static void

37、main(String args) System.out.print("請(qǐng)輸入字符串:");Scanner s = new Scanner(System.in);resourceCode = s.nextLine();buffer.append(resourceCode);if (sequenceList.indexOf(buffer.charAt(0) = -1) / 要檢測(cè)緩沖區(qū)字符flag = false;System.err.println("t由于包含非法字符,這不是句子!");return;if(buffer.charAt(0)!='

38、i'&&buffer.charAt(0)!='(')/不會(huì)出現(xiàn)第一個(gè)字符不是i和(的時(shí)候flag = false;System.err.println("t你的語(yǔ)法混亂,這不是句子!");return;for (int i = 1; i < buffer.length() - 2; i+) if (buffer.charAt(i) != 'i') if (buffer.charAt(i) = '(') /左括號(hào)后面只能接iif (buffer.charAt(i + 1) = ')'

39、| buffer.charAt(i + 1) = '+'| buffer.charAt(i + 1) = '*'| buffer.charAt(i + 1) = '/') flag = false;System.err.println("t你的語(yǔ)法混亂,這不是句子!");return;System.out.println("*");System.out.println("步驟tt棧tt輸入緩沖區(qū)");System.out.println(step+ + "tt" +

40、stack + "tt" + buffer);move();do top = stack.length() - 1;/ top指向棧頂?shù)谝粋€(gè)非終結(jié)符if (buffer.charAt(0) = '#') / 判斷退出if (stack.charAt(stack.length() - 2) = '#'&& stack.charAt(stack.length() - 1) = 'N') System.out.println();System.out.println("t該輸入串是句子,可以放心使用。&qu

41、ot;);break;if (stack.charAt(top) = 'N') top-;if (sequenceList.indexOf(buffer.charAt(0) = -1) / 每次要檢測(cè)緩沖區(qū)首字符flag = false;System.err.println("t由于包含非法字符,這不是句子!");return;compare(stack.charAt(top), buffer.charAt(0); while (flag);/* * 字符優(yōu)先級(jí)比較、進(jìn)棧、歸約 * */static void compare(char a, char b)

42、int i = sequenceList.indexOf(a);/ 行int j = sequenceList.indexOf(b);/ 列/ System.out.println(i+" "+j);switch (relationij) case 1:/ a>b,從棧頂找第二個(gè)終結(jié)符,準(zhǔn)備歸約int second;for (second = top - 1; stack.charAt(second) = 'N' second-) continue;i = sequenceList.indexOf(stack.charAt(top);j = seque

43、nceList.indexOf(stack.charAt(second);if (relationji = 0) / 棧頂首終結(jié)符和第二終結(jié)符優(yōu)先級(jí)相等/ stack.delete(second, top);/ stack.append('N');stack.replace(second, top + 1, "N");/ 從第二終結(jié)符到第一首終結(jié)符都除去,用N替換 else if (relationji = -1) / 棧頂首終結(jié)符優(yōu)先級(jí)高if (stack.charAt(top - 1) = 'N') / 如果左邊有N,則右邊也有,和兩邊的

44、N一起歸約stack.delete(top, top + 2);/ 刪除掉從start到end-1的字符 else / 只歸約它自己,他處于棧頂stack.deleteCharAt(top);stack.append('N');System.out.println(step+ + "tt" + stack + "tt" + buffer);break;case 0:/ a=b,b入棧case -1:/ a<b,b入棧move();break;default:/ 不能比較System.err.println(" "

45、 + a + "與" + b + "此時(shí)不能比較優(yōu)先級(jí),這個(gè)輸入串不是句子!");flag = false;return;/* * 將緩沖區(qū)首字符移到棧頂 */static void move() stack.append(buffer.charAt(0);buffer.deleteCharAt(0);System.out.println(step+ + "tt" + stack + "tt" + buffer);實(shí)驗(yàn)二運(yùn)行結(jié)果:實(shí)驗(yàn)三源代碼:import java.util.*;/* * author SXH *

46、 說(shuō)明 基于算符優(yōu)先分析方法的語(yǔ)法制導(dǎo)翻譯程序 */public class GrammarTransiation /* * 源串 * */static String resourceCode;/* * 判斷是否可以繼續(xù)執(zhí)行 */static boolean flag = true;/* * 棧 * */static StringBuilder stack = new StringBuilder("#");/* * 輸入緩沖區(qū) * */static StringBuilder buffer = new StringBuilder();/* * 步驟 */static int

47、 step = 1;/* * 四元式序號(hào) */static int siYianShi = 0;/* * 存放將要被歸約為N的他前面N的個(gè)數(shù) */static int n = 0;/* * 存放N對(duì)應(yīng)的值 */static String nValue = new String10;/* * 存放結(jié)果Tn */static int result = 1;/* * 棧頂?shù)谝粋€(gè)終結(jié)符 */static int top;/* * 字符順序表 *暫時(shí)用/表示 */static String sequenceList = "+*/i()#"/* * 優(yōu)先關(guān)系表,其中1為高于,0為等于,

48、-1為低于,-2為不能比 */static int relation = 1, -1, -1, -1, -1, 1, 1 , 1, 1, -1, -1, -1, 1, 1 , 1, 1, -1, -1, -1, 1, 1 , 1, 1, 1, -2, -2, 1, 1 , -1, -1, -1, -1, -1, 0, -2 , 1, 1, 1, -2, -2, 1, 1 , -1, -1, -1, -1, -1, -2, 0 ;/* * 主程序 */public static void main(String args) System.out.print("請(qǐng)輸入字符串:"

49、);Scanner s = new Scanner(System.in);resourceCode = s.nextLine();buffer.append(resourceCode);if (sequenceList.indexOf(buffer.charAt(0) = -1) / 要檢測(cè)緩沖區(qū)首字符flag = false;System.err.println("t由于包含非法字符,這不是句子!");return;if (buffer.charAt(0) != 'i' && buffer.charAt(0) != '(')

50、 / 不會(huì)出現(xiàn)第一個(gè)字符不是i和(的時(shí)候flag = false;System.err.println("t你的語(yǔ)法混亂,這不是句子!");return;for (int i = 1; i < buffer.length() - 2; i+) if (buffer.charAt(i) != 'i') if (buffer.charAt(i) = '(') / 左括號(hào)后面只能接iif (buffer.charAt(i + 1) = ')'| buffer.charAt(i + 1) = '+'| buffer.charAt(i + 1) = '*'| buffer.charAt(i + 1) = '/') flag = false;System.err.println("t你的語(yǔ)法混亂,這不是句子!");return;System.out.println("*");System.out.println("步驟tt棧tt輸入緩沖區(qū)");System.out.println(step+ + "tt" + stack + "tt" + buf

溫馨提示

  • 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)論