SNL編譯器設(shè)計(jì)實(shí)驗(yàn)報(bào)告_第1頁
SNL編譯器設(shè)計(jì)實(shí)驗(yàn)報(bào)告_第2頁
SNL編譯器設(shè)計(jì)實(shí)驗(yàn)報(bào)告_第3頁
SNL編譯器設(shè)計(jì)實(shí)驗(yàn)報(bào)告_第4頁
SNL編譯器設(shè)計(jì)實(shí)驗(yàn)報(bào)告_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、 編譯原理課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告目錄第一部分 實(shí)驗(yàn)成果統(tǒng)計(jì)表 1第二部分 實(shí)驗(yàn)簡介 2第三部分 詞法分析 3第四部分 語法分析 64.1 LL(1)法語法分析74.2 遞歸下降法語法分析10第五部分 語義分析19第六部分 程序測試22第七部分 實(shí)驗(yàn)總結(jié)與體會28第一部分 實(shí)驗(yàn)成果統(tǒng)計(jì)表姓名性別班級學(xué)號所占比例個(gè)人成績?nèi)蝿?wù)分工:(請用小四號宋體填寫)詞法分析部分程序的調(diào)試與實(shí)現(xiàn);LL(1)語法分析部分程序的調(diào)試與實(shí)現(xiàn);遞歸下降語法分析部分程序的調(diào)試與實(shí)現(xiàn);語義分析部分程序的調(diào)試與實(shí)現(xiàn);成績評定:詞法分析遞歸下降LL(1)語義分析團(tuán)隊(duì)成績教師簽章備注填寫說明:1、請將首頁紅色部分信息填全,其中:班級為2

2、位數(shù)字,保留首位的0;學(xué)號為8位數(shù)字,計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院以53開頭;所占比例為百分?jǐn)?shù),精確到個(gè)位數(shù),且所有人的所占比例之和為100%;不足四人的分組請保留后面的多余空行,請勿修改該表的結(jié)構(gòu)。2、請根據(jù)實(shí)際情況填寫任務(wù)分工部分,主要任務(wù)包括:編譯系統(tǒng)的總體分析與設(shè)計(jì),四個(gè)具體功能的設(shè)計(jì)與實(shí)現(xiàn),對應(yīng)的測試與驗(yàn)證過程(報(bào)告正文需要列出若干組具體測試樣例與對應(yīng)結(jié)果),系統(tǒng)界面的設(shè)計(jì)與美工,以及輔助工具、視圖和文件等。3、成績評定部分由指導(dǎo)教師填寫,請勿填寫和修改。第二部分 實(shí)驗(yàn)簡介本實(shí)驗(yàn)中實(shí)現(xiàn)了SNL編譯系統(tǒng)中的詞法分析、語法分析和語義分析。其中語法分析包括遞歸下降分析方法和LL(1)分析方法。詞法

3、分析,以源程序?yàn)檩斎耄蓡卧~的內(nèi)部表示TOKEN序列。語法分析,以TOKEN序列為輸入進(jìn)行語法分析,并生成整個(gè)源程序的語法分析樹。在SNL編譯程序中,采用了兩種語法分析方法實(shí)現(xiàn):LL(1)和遞歸下降法。兩種語法分析的結(jié)果是一樣的。語義分析,以語法樹為輸入生成標(biāo)識符的屬性符號表以及相關(guān)的各類信息表,如數(shù)組信息表,并進(jìn)行相關(guān)的語義檢查。它們?nèi)叩年P(guān)系如下:LL(1)語法分析遞歸下降語法分析詞法分析語義分析第三部分 詞法分析源程序一般表現(xiàn)為字符串(機(jī)器語言稱其為ASCII碼)序列的形式,而編譯程序的翻譯工作應(yīng)該在單詞一級上進(jìn)行,這與自然語言的翻譯理解過程是類似的。因此要進(jìn)行編譯工作,首先要把源程序

4、的字符序列翻譯成單詞序列。詞法分析是編譯過程的第一階段。它的任務(wù)就是對輸入的字符串形式的源程序按順序進(jìn)行掃描,根據(jù)源程序的詞法規(guī)則識別具有獨(dú)立意義的單詞(符號),并輸出與其等價(jià)的TOKEN序列。TOKEN是單詞(符號)的內(nèi)部表示。完成詞法分析任務(wù)的程序稱為詞法分析程序,通常也稱為詞法分析器或掃描器(scanner)。TOKEN是單詞在編譯程序處理過程中的一種內(nèi)部表示,也是詞法分析程序?qū)Τ绦蛑懈黝悊卧~進(jìn)行處理之后的輸出形式。對于一種語言而言,如何對它的單詞進(jìn)行分類,每一類單詞的TOKEN數(shù)據(jù)結(jié)構(gòu)的形式如何,都沒有固定的模式,可以隨編譯程序的不同而不同。通常TOKEN的結(jié)構(gòu)可以分成兩部分,單詞的語

5、法信息和語義信息。其中語法信息記錄的是這個(gè)單詞的種類,語義信息則記錄著這個(gè)單詞的具體信息。這樣,就能為以后的語法分析和語義分析處理單詞做好準(zhǔn)備。SNL語法分析對每類單詞的分析結(jié)果的TOKEN結(jié)構(gòu)為三元組(詞法信息、語義信息以及該單詞在源程序中的行號)。本SNL編譯器單詞的內(nèi)部表示如下:行號(便于出錯處理)TOKEN的內(nèi)部表示語法信息及其字符串表示語義信息及其字符串表示SNL語言的單詞分類如下:(1):保留字 保留字一般是由語言系統(tǒng)自身定義的, SNL語言中的保留字有program,while,if,fi等等。(2):標(biāo)識符 用來標(biāo)識程序中各個(gè)對象的名稱。由用戶自己定義用來表示變量名,數(shù)組名或者

6、過程名等。SNL語言中標(biāo)識符由字母開頭,字母、數(shù)字的任意組合組成的。(3):常量 用來表示各類常數(shù)。如字符型常量,實(shí)行常量,布爾常量等。(4):運(yùn)算符 表示程序中算術(shù)運(yùn)算、邏輯運(yùn)算、字符運(yùn)算的確定字符或字符串。SNL語言中的運(yùn)算符有+,*,/,加法運(yùn)算符關(guān)系運(yùn)算符左括號棧底標(biāo)志END。predict()函數(shù)根據(jù)產(chǎn)生式編號選擇一個(gè)要執(zhí)行的函數(shù)。newnode()函數(shù)用于生成樹節(jié)點(diǎn)。TeeToFile()函數(shù)用于將最后產(chǎn)生的語法樹寫入SynTree.txt文件,該文 件可以查看語法樹,也可以在需要顯示輸出時(shí)從中讀取語法樹。printTree()函數(shù)用于從SynTree.txt中讀出語法樹,然后輸出

7、顯示。StrToEnum()用于將從Tokenlist.txt中讀取的以字符串形式存在的TOKEN的Lex域轉(zhuǎn)換成LexType枚舉類型。PushSym()用于將當(dāng)前符號入棧到符號棧。PopSym()用于將符號棧棧頂符號出棧。PushSynTree()用于將當(dāng)前語法樹節(jié)點(diǎn)中指向兒子或兄弟節(jié)點(diǎn)的指針的地址入棧到語法樹棧。PopSynTree()用于將語法樹棧棧頂指向樹節(jié)點(diǎn)的指針的地址出棧。PushOp()用于將當(dāng)前操作符入棧到操作符棧。PopOp()用于將操作符棧棧頂操作符出棧。ReadOpStack()用于讀取操作符棧棧頂操作符。PushNum()用于將當(dāng)前操作數(shù)入棧。PopNum()用于將操

8、作數(shù)棧棧頂操作數(shù)出棧。LL(1)語法分析主函數(shù)parseLL1()的算法框圖如下: 4.2 遞歸下降法(一)、遞歸下降語法基本原理綜述語法分析是編譯程序的第二階段,語法分析的任務(wù)是根據(jù)語言的語法規(guī)則對源程序進(jìn)行語法檢查,并識別出相應(yīng)的語法成分。簡單地說,語法分析就是根據(jù)語言的語法規(guī)則對語言的句子結(jié)構(gòu)進(jìn)行分析,看源程序的句子結(jié)構(gòu)是否符合語言語法規(guī)則的要求。語法分析的輸入是從詞法分析器輸出的TOKEN序列形式,然后根據(jù)語言的文法規(guī)則進(jìn)行分析處理,語法分析的輸出是無語法錯誤的語法分析樹的形式。這一部分主要介紹遞歸下降法語法分析的原理及實(shí)現(xiàn)。遞歸下降法是語法分析中比較容易理解的一種方法,因?yàn)槠洳捎昧诉f

9、歸的結(jié)構(gòu)和思想,但這也在一定程度上影響了程序的執(zhí)行效率,所以這種方法的優(yōu)點(diǎn)是容易實(shí)現(xiàn),容易理解,缺點(diǎn)就是這種方法的執(zhí)行效率不如LL(1)高。遞歸下降法的主要原理是對每個(gè)終極符和非終極符按其產(chǎn)生式結(jié)構(gòu)構(gòu)造相應(yīng)的語法分析子程序,其中終極符產(chǎn)生匹配命令,而非終極符則產(chǎn)生過程調(diào)用命令。其中子程序結(jié)構(gòu)與產(chǎn)生式的結(jié)構(gòu)幾乎是一致的。前面我們已經(jīng)提到對于終極符將產(chǎn)生匹配命令match(),match()命令的定義如下:Match(x) 無定義, x屬于Vn 檢查token=x? 若是,則移位;否則,報(bào)錯, x屬于Vt根據(jù)遞歸下降法的基本原理和思想,我們可以將遞歸下降法語法分析主程序?qū)懗扇缦碌男问?,這個(gè)程序形式

10、就是我我們所編寫的遞歸下降法語法分析程序的主程序格式,這樣就可以容易構(gòu)造出一個(gè)文法的語法分析程序:Program p token:類型;Begin 讀入一個(gè)toke if token 屬于 First(S) then S else 報(bào)錯并停機(jī)End(二)、遞歸下降語法分析程序的主要處理對象及其依賴關(guān)系我們編寫的遞歸下降語法分析程序主要對一個(gè)程序的主要部分進(jìn)行分析和檢查,其中主要包括程序頭、程序聲明、類型聲明、變量聲明、過程聲明、程序體(包括各種語句序列、表達(dá)式)等,下面對各部分做簡要的說明:程序頭:程序的開始,包括保留字以及程序的名字。程序聲明:包括程序的整個(gè)聲明部分,又可以細(xì)分為類型聲明、變

11、量聲明、過程聲明等。類型聲明:用于定義類型,其中類型可以分為基本類型(整型、字符型等)、結(jié)構(gòu)類型(數(shù)組類型、記錄類型等)和自定義類型(類型名稱為標(biāo)識符,實(shí)際類型為上述兩種類型)。變量聲明:用于聲明變量,定義變量類型。過程聲明:用于聲明過程,包括參數(shù)(變參、值參)、過程中的聲明和過程體。程序體:由語句序列組成,語句主要包括賦值語句、條件語句、循環(huán)語句、輸入語句、輸出語句、返回語句、過程調(diào)用語句(可由讀入的標(biāo)識符或者其它相應(yīng)的保留字來判定屬于哪一種語句,并選擇相應(yīng)的程序進(jìn)行分析。)對語句的分析可能會涉及到對表達(dá)式的處理。 給出了遞歸下降語法分析程序所要分析處理的各種語法成分,為了能更清楚直接地反映

12、出各語法成分之間的依賴關(guān)系,參考實(shí)驗(yàn)教材上的內(nèi)容,我們給出了遞歸下降語法分析中各語法成分的依賴圖,如下圖所示:總程序程序頭程序聲明類型聲明變量聲明過程聲明參數(shù)聲明過程中的聲明過程體(主體程序)語句序列語句表達(dá)式圖1. 遞歸下降語法分析中各語法成分的依賴關(guān)系(三)、遞歸下降語法分析輸出結(jié)果語法分析樹根據(jù)上面的敘述,我們知道遞歸下降語法分析程序的輸入是通過詞法分析程序產(chǎn)生的TOKEN序列,而作為語法分析程序的輸出,我們給出了遞歸下降語法分析程序的統(tǒng)一規(guī)范化輸出結(jié)果語法分析樹的基本形式。我們編寫的遞歸下降語法分析程序最終的輸出結(jié)果就是下面語法樹的形式,只不過我們是以另一種形式組織并保存在.txt文件

13、中,但核心的思想就是下圖所示的語法樹形式。該語法樹形式不僅體現(xiàn)了語法分析程序的輸出結(jié)果,還在一定程度上反映出了各語法分析成分之間的關(guān)系。圖2. 語法分析樹(四)、遞歸下降語法分析程序主要函數(shù)介紹根據(jù)之前的分析和敘述,我們已經(jīng)對遞歸下降語法分析程序進(jìn)行了最基本的闡述,這些基本的闡述可以使得我們很清楚地了解遞歸下降語法分析程序所要實(shí)現(xiàn)的功能、所要分析的對象以及優(yōu)缺點(diǎn)等。下面我們將對遞歸下降語法分析程序中的主要函數(shù)進(jìn)行介紹,主要介紹函數(shù)的聲明和功能等,并在最后給出各主要函數(shù)之間的調(diào)用關(guān)系。按照這些函數(shù)的聲明和調(diào)用關(guān)系,我們便可以基本實(shí)現(xiàn)遞歸下降語法分析程序的功能。主要函數(shù)聲明:主要函數(shù)功能描述:Tr

14、eeNode* parseMain(void)1.調(diào)用總程序處理分析函數(shù):創(chuàng)建語法分析樹,同時(shí)處理文件的提前結(jié)束錯誤。TreeNode* program(void);2 總程序處理分析程序:生成語法分析樹的根節(jié)點(diǎn)root,分別調(diào)用程序頭部分、聲明部分、程序體部分分析函數(shù)并成為語法樹的3個(gè)節(jié)點(diǎn)TreeNode* programHead(void)3 程序頭部分分析處理函數(shù):根據(jù)讀入的單詞,匹配保留字PROTGRAM,記錄程序名于程序頭結(jié)點(diǎn),匹配IDTreeNode* declarePart(void)4 程序聲明部分分析函數(shù):根據(jù)文法產(chǎn)生式創(chuàng)建新的類型聲明標(biāo)志節(jié)點(diǎn)、變量聲明標(biāo)志節(jié)點(diǎn)。調(diào)用類型聲明

15、部分處理函數(shù)TypeDec()、變量聲明部分處理函數(shù)VarDec()、過程聲明部分處理函數(shù)ProcDec()TreeNode* typeDec(void)5類型聲明部分處理函數(shù): 根據(jù)讀入的下個(gè)單詞,若當(dāng)前單詞為TYPE,調(diào)用函數(shù)typeDeclaration()并賦值給t,則函數(shù)返回t,否則返回NULLTreeNode* typeDeclaration(void)6類型聲明中的其他函數(shù):根據(jù)文法產(chǎn)生式,匹配保留字TYPE,調(diào)用函數(shù)TypeDecList()并賦值給t,若t為NULL則顯示提示信息。函數(shù)返回tTreeNode* typeDecList(void)7函數(shù)聲明中的其它函數(shù):根據(jù)文法

16、產(chǎn)生式,創(chuàng)建新的聲明類型節(jié)點(diǎn)t。若申請成功,調(diào)用函數(shù)TypeId(),匹配保留字EQ,調(diào)用函數(shù)TypeDef(),匹配保留字SEMI,調(diào)用函數(shù)TypeDecMore(),返回值賦值給t的成員sibling,函數(shù)返回tTreeNode* typeDecMore(void)8類型聲明中的其它函數(shù):該函數(shù)根據(jù)讀入的單詞,或者調(diào)用函數(shù)TypeDecList()并賦值給t,則函數(shù)返回t;或者什么都不做,或者跳過此錯誤單詞,讀入下一個(gè)單詞,返回NULLvoid typeId(TreeNode* t)9類型聲明中類型標(biāo)識符處理分析程序:該函數(shù)根據(jù)讀入的單詞,判斷TOKEN.Lex=ID的值,如果為真則將TO

17、KEN.Sem字符串拷貝到參數(shù)t的成員tnum中,其中tnum是用來記錄namne個(gè)數(shù)的臨時(shí)變量。然后再將tnum加1送回參數(shù)t的成員attr.idnumvoid typeDef(TreeNode* t)10具體類型處理分析函數(shù):該函數(shù)根據(jù)讀入的單詞,或者調(diào)用BaseType(),或者調(diào)用structureType(),或者復(fù)制標(biāo)識符名稱、匹配標(biāo)識符,或者跳過錯誤單詞,讀入下一個(gè)單詞void baseType(TreeNode* t)11基本類型分析處理函數(shù):該函數(shù)根據(jù)讀入的單詞判斷執(zhí)行哪個(gè)分支void structureType(TreeNode* t)12結(jié)構(gòu)類型處理分析

18、函數(shù):該函數(shù)根據(jù)讀入的單詞判斷選擇調(diào)用函數(shù)ArrayType(),或者調(diào)用函數(shù)RecType()void arrayType(TreeNode* t)13 數(shù)組類型的分析處理函數(shù):該函數(shù)對讀入的單詞進(jìn)行匹配,并記錄數(shù)組的上界和下界,再匹配保留字,最后調(diào)用基本類型函數(shù)yBaseType(),記錄數(shù)組的子類型void recType(TreeNode* t)14記錄類型的處理分析函數(shù):該函數(shù)對讀入的單詞進(jìn)行匹配,調(diào)用記錄中的域函數(shù)FieldRec(),最后再對讀入的單詞進(jìn)行匹配TreeNode* fieldDecList(void)15記錄類型中的域聲明處理分析函數(shù):該函數(shù)根據(jù)讀入的單詞判斷記錄域

19、中的變量屬于哪種類型,根據(jù)產(chǎn)生式的select集合判斷執(zhí)行哪個(gè)分支程序。其中相同類型的變量id用“,”分隔開,其名稱記錄在語法書的同一個(gè)節(jié)點(diǎn)中,不同類型的變量節(jié)點(diǎn)互為兄弟節(jié)點(diǎn)TreeNode* fieldDecMore(void)16記錄類型中的其他域聲明處理分析函數(shù):該函數(shù)根據(jù)文法產(chǎn)生式判斷讀入的單詞,若為END,則不做任何處理;若為INTEGER,CHAR或者ARRAY,則調(diào)用FieldDecList()遞歸處理函數(shù);否則讀入下一個(gè)TOKEN序列,函數(shù)返回tvoid idList(TreeNode* t)17記錄類型域中標(biāo)識符名處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式,匹配標(biāo)識符ID,記錄標(biāo)識符

20、名稱,調(diào)用遞歸處理函數(shù)IdMore()void idMore(TreeNode* t)18記錄類型域中其他標(biāo)識符名處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式判斷讀入的單詞,處理調(diào)用相應(yīng)的函數(shù)TreeNode* varDec(void)19變量聲明處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式判斷讀入的單詞,處理調(diào)用相應(yīng)的函數(shù)。如果處理成功則返回t,否則返回NULL。TreeNode* varDeclaration(void)20變量聲明部分處理程序:該函數(shù)根據(jù)文法產(chǎn)生式,匹配保留字VAR,調(diào)用函數(shù)VarDecList()函數(shù)。處理成功返回t,否則返回NULLTreeNode* varDecList(void)21

21、變量聲明部分處理程序:該函數(shù)根據(jù)文法產(chǎn)生式調(diào)用相應(yīng)的變量聲明部分的處理函數(shù)TypeDef(),VarIdList(),VarDecMore()。處理成功返回t,否則返回NULLTreeNode* varDecMore(void)22變量聲明部分處理程序:該函數(shù)根據(jù)文法產(chǎn)生式。由讀入的單詞判斷執(zhí)行哪個(gè)分支,最后返回tvoid varIdList(TreeNode* t)23變量聲明部分變量名部分處理程序:該函數(shù)根據(jù)文法產(chǎn)生式,匹配標(biāo)識符名ID,記錄標(biāo)識符名稱,調(diào)用函數(shù)VarIdMore()。void varIdMore(TreeNode* t)24變量聲明部分變量名部分處理程序:該函數(shù)根據(jù)文法產(chǎn)

22、生式,由讀入的單詞判斷執(zhí)行哪個(gè)分支(判斷是否還有其他變量)TreeNode* procDec(void)25過程聲明部分總的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式判斷當(dāng)前單詞,若為BEGIN則不做任何動作,若為PROCEDURE,則調(diào)用過程聲明函數(shù)ProcDeclaration(t),否則讀入下一個(gè)單詞。函數(shù)返回tTreeNode* procDeclaration(void)26該函數(shù)根據(jù)文法產(chǎn)生式匹配保留字PROCEDURE,調(diào)用過程名函數(shù)ProcName(),參數(shù)函數(shù)ParamList(),過程體內(nèi)部聲明部分函數(shù)ProcDecPart(),過程體函數(shù)ProcBody()。成功則返回t,否則返回

23、NULL。void paramList(TreeNode* t)27過程聲明中的參數(shù)聲明部分的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式判斷讀入的單詞,若為RPAREN,則不做任何動作;若為INTEGER,CHAR,ARRAY,RECORD,ID,VAR,則調(diào)用參數(shù)聲明序列處理函數(shù)ParamDecList(t),否則讀下一個(gè)TOKEN序列TreeNode* paramDecList(void)28過程聲明中的參數(shù)聲明序列的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式調(diào)用函數(shù)Param(),返回指針t;調(diào)用函數(shù)paramMore(),返回指針p。若p不為NULL,則將p賦值給t的成員變量sibling。若處理成功

24、則返回指針t,否則返回NULLTreeNode* paramMore(void)29過程聲明中的參數(shù)聲明其他部分的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式,由讀入的單詞判斷執(zhí)行哪個(gè)分支(判斷是否還有其他參數(shù)聲明)。TreeNode* Param(void)30過程聲明中的參數(shù)聲明中參數(shù)部分的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式,由讀入的單詞判斷執(zhí)行哪個(gè)分支程序,即判斷是值參還是變參。處理成功返回t,否則返回NULLvoid formList(TreeNode* t)31過程聲明中的參數(shù)聲明中參數(shù)名部分的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式,記錄參數(shù)聲明中的參數(shù)名稱,匹配保留字ID,調(diào)用FidMore()

25、函數(shù)。void fidMore(TreeNode* t)32過程聲明中的參數(shù)聲明中參數(shù)名部分的處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式,有讀入的單詞判斷執(zhí)行哪個(gè)分支程序。TreeNode* procDecPart(void)33過程中聲明部分的分析處理程序:該函數(shù)根據(jù)文法產(chǎn)生式,調(diào)用聲明部分函數(shù)DeclarationPart(),如果處理成功則返回t,否則返回NULL。TreeNode* procBody(void)34過程體部分處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式,調(diào)用程序體部分函數(shù)ProgramBody().成功則返回t,否則返回NULL。TreeNode* programBody(void)35

26、主程序體部分處理分析程序:根據(jù)文法產(chǎn)生式創(chuàng)建新的語句標(biāo)志類型語法樹節(jié)點(diǎn),并匹配保留字,調(diào)用語句序列函數(shù)StmList()TreeNode* stmList(void)36語句序列部分處理分析程序:根據(jù)文法產(chǎn)生式,調(diào)用語句處理函數(shù)Stm(),返回指針t;調(diào)用更多語句處理函數(shù)StmMore(),返回指針p,并使p成為t的兄弟節(jié)點(diǎn)。TreeNode* stmMore(void)37更多語句部分處理分析程序: 根據(jù)文法產(chǎn)生式,由讀入的單詞判斷執(zhí)行哪個(gè)分支,即是否有更多的語句。TreeNode* stm(void)38語句遞歸處理分析程序:根據(jù)讀入的單詞和每條產(chǎn)生式的Predict集選擇調(diào)用相應(yīng)的語句處

27、理函數(shù)。(書中有更詳細(xì)的說明)TreeNode* assCall(void)39賦值語句和過程調(diào)用語句部分的處理分析程序:根據(jù)讀入的單詞選擇相應(yīng)的處理程序(賦值語句處理程序和過程調(diào)用語句處理程序)TreeNode* assingmentRest(void)40賦值語句處理分析函數(shù):根據(jù)文法產(chǎn)生式,創(chuàng)建新的賦值語句類型語法樹節(jié)點(diǎn)。匹配保留字EQ,調(diào)用表達(dá)式函數(shù)Exp()。TreeNode* conditionalStm(void)41條件語句處理分析程序:該函數(shù)根據(jù)文法產(chǎn)生式匹配保留字IF,調(diào)用表達(dá)式函數(shù)Exp();匹配保留字THEN,調(diào)用語句序列函數(shù)StmL()(此處的語句序列函數(shù)不同于前處的

28、StmList()函數(shù)。具體更詳盡的說明見書P104)TreeNode* loopStm(void)42循環(huán)語句處理分析程序:根據(jù)文法產(chǎn)生式,匹配保留字WHILE,調(diào)用表達(dá)式處理函數(shù)Exp(),再匹配保留字DO,調(diào)用語句序列處理函數(shù),最后匹配保留字ENDWH。TreeNode* inputStm(void)43輸入語句的處理分析函數(shù):根據(jù)文法產(chǎn)生式,創(chuàng)建新的輸入語句類型語法樹節(jié)點(diǎn)t,匹配保留字READ,LPAREN,記錄標(biāo)識符名稱,匹配ID,RPAREN。TreeNode* outputStm(void)44輸出語句處理分析程序:根據(jù)文法產(chǎn)生式,創(chuàng)建新的輸出語句類型語法樹節(jié)點(diǎn)t,匹配保留字WR

29、ITE,LPAREN,調(diào)用函數(shù)Exp(),匹配保留字RPAREN。TreeNode* returnStm(void)45過程返回語句處理分析程序:根據(jù)文法產(chǎn)生式,創(chuàng)建新的過程返回類型的語法樹節(jié)點(diǎn)t,匹配保留字RETURN。TreeNode* callStmRest(void)46過程調(diào)用語句處理分析程序:根據(jù)文法產(chǎn)生式,創(chuàng)建新的過程調(diào)用類型語法樹節(jié)點(diǎn)t,匹配保留字LPAREN,調(diào)用實(shí)參處理分析函數(shù)ActParamList(),匹配RPAREN。TreeNode* actParamList(void)47實(shí)參部分處理分析程序: 根據(jù)讀入的單詞選擇執(zhí)行哪段程序(有參數(shù)或者無參數(shù))TreeNode*

30、 actParamMore(void)48更多實(shí)參部分處理分析程序: 根據(jù)讀入的單詞決定執(zhí)行哪段分支程序。TreeNode* exp(void)49表達(dá)式遞歸處理分析程序: 根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù)。TreeNode* simple_exp(void)50根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù)。TreeNode* term(void)51項(xiàng)遞歸處理分析程序: 根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù)。TreeNode* factor(void)52 因子遞歸處理分析程序: 根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù)。TreeNode* variable(void)53變量處理程序: 根

31、據(jù)產(chǎn)生式,生成一個(gè)新的表達(dá)式節(jié)點(diǎn)t,如果創(chuàng)建成功且當(dāng)前單詞為ID,則記錄并匹配ID,調(diào)用變量其余部分處理函數(shù)variMore(t),返回t。void variMore(TreeNode* t)54變量其余部分處理程序:根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù)。如果當(dāng)前單詞為ASSIGN等,則不作任何處理;如果當(dāng)前單詞為LMIDPAREN,則調(diào)用Exp()處理表達(dá)式;如果當(dāng)前單詞為DOT,則匹配DOT處理域變量函數(shù)fieldvar();否則讀下一個(gè)TOKENTreeNode* fieldvar(void)55域變量部分處理過程: 根據(jù)文法產(chǎn)生式,生成一個(gè)新的表達(dá)式節(jié)點(diǎn)t,如果創(chuàng)建成功且當(dāng)前單詞為I

32、D,則記錄并匹配ID,調(diào)用域變量其余部分處理函數(shù)fieldvarMore(t),返回tvoid fieldvarMore(TreeNode* t)56域變量其他部分處理過程: 根據(jù)文法產(chǎn)生式,調(diào)用相應(yīng)的遞歸處理函數(shù)。如果當(dāng)前單詞為ASSIGN,則不作任何處理;如果當(dāng)前單詞為LMIDPAREN,則調(diào)用Exp()處理表達(dá);否則讀入下一個(gè)TOKENvoid match(LexType expected)57 終極符匹配處理程序: 該函數(shù)將當(dāng)前單詞與函數(shù)參數(shù)給定的單詞相比較,如果一致則取下一個(gè)單詞,都則退出語法分析程序。(五)、遞歸下降語法分析程序中各函數(shù)的調(diào)用關(guān)系函數(shù)parseMain()函數(shù)Pro

33、gram()函數(shù)ProgramHead()函數(shù)DeclarePart()函數(shù)TypeDec()函數(shù)TypeName()函數(shù)VarDec()函數(shù)ProcDec()函數(shù)ParamList()函數(shù)ProcDecPart()函數(shù)ProcBody()函數(shù)ProgramBody()函數(shù)StmList()函數(shù)Stm()函數(shù)Exp()函數(shù)simple_exp()函數(shù)term()函數(shù)factor()圖3. 主要函數(shù)的調(diào)用關(guān)系(六)、遞歸下降語法分析實(shí)驗(yàn)總結(jié)與體會 通過將近8周的學(xué)習(xí)和編程,我實(shí)現(xiàn)了遞歸下降語法分析程序的基本功能并且通過調(diào)試可以使得程序能正確運(yùn)行并產(chǎn)生預(yù)期的結(jié)果。雖然我參考了書中很多內(nèi)容才將本模塊

34、程序?qū)崿F(xiàn),但是這個(gè)過程使我受益匪淺:我學(xué)會了上網(wǎng)搜集相關(guān)內(nèi)容和源程序;也鍛煉了我的學(xué)習(xí)和調(diào)試程序的能力;同時(shí)對于一些不完善的細(xì)節(jié)我通過自己的努力進(jìn)行重新編程和糾錯,最終完成了程序的相關(guān)功能;更重要的是我學(xué)會了與小組成員更好更高效地交流和合作,從而使得我們能順利地完成了這次編程任務(wù)。大學(xué)三年以來,我們還是第一次接觸這么大型的程序開發(fā),感覺很新鮮,很有成就感,這個(gè)過程也使得我們對高級語言編程更加熟練。不過由于時(shí)間和個(gè)人能力有限,我的源程序很大一部分都參考了實(shí)驗(yàn)書中的內(nèi)容,所以實(shí)驗(yàn)效果不是很理想。不過通過這次實(shí)驗(yàn)確實(shí)讓我學(xué)到很多,我也會借此繼續(xù)完善和強(qiáng)化自己,爭取能不斷地提高自己編程和實(shí)踐能力,為以

35、后的研究生學(xué)習(xí)和工作打下基礎(chǔ)。第五部分 符號表管理與語義分析一、概述語義分析(Semantic Analysis)是任何編譯程序必不可少的一個(gè)階段,也是編譯程序中最實(shí)質(zhì)性的工作。在整個(gè)編譯過程中,詞法分析和語法分析是對源程序形式上的識別和處理,而語義分析程序是對源程序的語義做相應(yīng)的處理工作。語義分析的主要任務(wù)是針對語法分析后得到的內(nèi)部結(jié)構(gòu)進(jìn)行語義處理,既要做相應(yīng)的語義分析檢查工作,還要為后面的編譯工作提供足夠的信息,這些信息包括標(biāo)識符的語義信息、類型信息、過程信息等。二、語義分析的主要任務(wù)1. 構(gòu)造符號表和信息表2. 進(jìn)行語義錯誤檢查,主要包括標(biāo)識符重復(fù)定義、標(biāo)識符未聲明、標(biāo)符類型不符、引用不

36、合法等3. 如果語義分析無錯誤,輸出符號表內(nèi)容,否則將錯誤信息輸出到指定文件中符號表格式標(biāo)識符名: 類型信息 層號 偏移 直/間接變量示例a: intTy varkind Level = 0 Offset = 7 dir錯誤信息格式(行號):標(biāo)識符名 錯誤信息示例(5):a 未聲明的類型標(biāo)識符三、具體實(shí)現(xiàn)1. 符號表設(shè)計(jì)與實(shí)現(xiàn)本程序的符號表的構(gòu)建是使用駐留法進(jìn)行實(shí)現(xiàn)的,從而在程序運(yùn)行結(jié)束時(shí),所有標(biāo)識符的信息均能繼續(xù)保存在符號表中,方便進(jìn)行后續(xù)操作,且使用駐留法實(shí)現(xiàn)的符號表更易理解和操作。SymbTable * scope128;/符號標(biāo)定義,大小為128int symbtop;/存儲符號表末尾

37、下標(biāo),初始為-1typedef struct symbtablechar idname10; /存儲標(biāo)識符名稱,為“#”是表示一層的結(jié)束AttributeIR attrIR;/存儲標(biāo)識符詳細(xì)信息int next;/當(dāng)標(biāo)識符名為“#”時(shí)有效,存儲該層入口結(jié)點(diǎn)在scope中的位置SymbTable;/符號表結(jié)點(diǎn)定義private:int stack10;/存儲每一層入口結(jié)點(diǎn)在scope中的位置void Push(int s);/每進(jìn)入新的一層時(shí),將入口結(jié)點(diǎn)下標(biāo)入棧int Pop();/沒離開一層時(shí),將入口結(jié)點(diǎn)下標(biāo)出棧int GetTop();/獲取當(dāng)前層的起始位置示例:SNL源代碼為:progra

38、m ptype t1 = integer;var t1 v1;procedure q(var integer i);procedure r(integer j)beginwrite(j);endbeginr(i);i:=i+10;endbeginread(v1);q(v1)end.則生成的符號表為:位置 Idname attrIR next0t1詳細(xì)信息-11v1詳細(xì)信息-12q詳細(xì)信息-13i詳細(xì)信息-14r詳細(xì)信息-15j詳細(xì)信息-16#NULL27#NULL42. 語義分析部分設(shè)計(jì)與實(shí)現(xiàn)(1) 整體設(shè)計(jì)有語義錯誤輸出錯誤信息無語義錯誤打印符號表查找查找創(chuàng)建讀入回填語義分析符號表符號表維護(hù)

39、語法樹 (2) 主要函數(shù)聲明及其功能void Start(TreeNode *t);/語法分析部分入口函數(shù),輸入為語法分析部分生成的語法樹的根節(jié)點(diǎn),函數(shù)體內(nèi)包含語法分析的主題框架bool Enter(char *id, AttributeIR *Att, SymbTable *Entry);/參數(shù)為標(biāo)識符名,指向詳細(xì)信息的指針,以及指向符號表的指針的指針,函數(shù)功能是查尋標(biāo)識符定義是否正確,如果正確將Att中的信息填寫入符號表,否則返回falsebool FindAll(char *id, SymbTable *Entry);/在整個(gè)符號表中查找標(biāo)識符名為id的項(xiàng)bool Find(char *id, SymbTable *Entry);/在當(dāng)前層符號表中查找標(biāo)識符名為id的項(xiàng)bool FindField(char *id, Fie

溫馨提示

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

最新文檔

評論

0/150

提交評論