一個簡單的C語言編譯器_第1頁
一個簡單的C語言編譯器_第2頁
一個簡單的C語言編譯器_第3頁
一個簡單的C語言編譯器_第4頁
一個簡單的C語言編譯器_第5頁
已閱讀5頁,還剩12頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、一個簡單的C語言編譯器.小組成員嘉筱杭林朱王朱朱()()()計算機996計算機996計算機996計算機994在DO*境下運行:Cminus.exe<filename>-h三.概述經過一段時間的學習,我們在初步掌握了編譯器的基本原理以后,設計了一個具有基本編譯功能的編譯器。該編譯器接受類C語言語法的源代碼輸入,輸出結果是PC機的匯編源代碼。在捆綁了宏匯編編譯器Masmt,即可直接生成MSDOS的二進制可執行文件。為方便起見,以下簡稱為C語言編譯器。本編譯器實現了基本高級語言所必須的語法要素,包括簡單變量聲明、函數的實現、整數和字符串運算、條件判斷語句和循環語句及跳轉語句、基本代數運算

2、、賦值等,還支持匯編語言嵌入。本編譯器是利用編譯器生成器ParseGenerator和VC6.0在Windows平臺上實現的,并開發了一個基于Windows平臺的32位編譯集成開發環境CompilerMan,提供了關鍵字彩色提示、出錯同屏提示、出錯代碼跳轉等較為完善方便的功能。由于編譯程序本身涉及到詞法分析、語法分析、代碼生成、錯誤恢復和優化等諸多模塊,要在實驗中做到面面俱到不太可能,所以本編譯器不可避免的會存在各種問題,但作為一個具有基本功能的、可擴充的系統,完全達到了鞏固編譯原理的理論知識,并將其運用于實踐的目的。四.背景編譯程序,就是一種具有編撰和翻譯功能的程序。人們要用計算機來解決問題

3、,首先面臨的一個問題,就是要告訴計算機解決什么問題,或者告訴計算機如何解決這個問題。這就涉及到用什么樣的語言來描述的問題,人所習慣的自然語言和計算機認識的機器語言有很大的差別,用機器語言來描述人想解決的問題十分不便,因而,計算機科學家設計一些人們比較習慣的語言來描述要解決的問題,稱之為B級語言。用語言來描述的問題,統稱為程序。然而,用高級語言寫的程序,不能被計算機所直接認識和理解,必須經過等價的轉換,變成機器能理解并執行的機器語言的程序。進行這種等價轉換工作的工具,就是編譯程序。1 .編譯程序的結構編譯程序是很復雜的,但它可被分為相對獨立的幾個部分,每個部分承擔專門的工作,各部分間互相共享傳送

4、數據。把編譯程序分解成較小的部分,不僅便于開發、調試,而且便于編譯程序的移植。一個典型的編譯程序通常具有如圖1的結構目標機器碼圖1編譯器基本結構1.1 詞法分析詞法分析負責對源程序的字符串進行掃描和分解,根據構詞法將字符流(CharacterStream,專化成單詞流(TokenStream)。例如對于C-語句:x=y+z-m*10;詞法分析的結果是:IDASSIGNIDADDIDSUBIDMULNUMSEMI構詞的規則就是詞法,例如標識符(ID)可定義為以字母開頭,后面跟零個或任意個字母或數字的序列。詞法分析程序就根據詞法構造有限自動機來識別每一個單詞,將產生的單詞交給語法分析程序。1.2

5、語法分析語法分析模塊的任務是根據文法規則把單詞序列分解成各類語法單位,識別出一個一個句子,例如對前面的語句進行語法分析可得到如圖2的分析樹。如果輸入單詞不能構成語法樹,則說明有語法錯誤。常見的語法分析方法分為自頂向下分析和自底向上分析兩大類。在C-編譯器中采用了一種自底向上的方法,即LR方法。圖2語法分析樹1.3 語義分析這一階段部分是根據前一階段產生的語法樹,按語言的語義進行翻譯,產生四元式或三元式等中間語言。中間語言可以很方便地轉換成目標代碼。前面的語法樹可能產生的四元式序列為:(*,_t0,10,m)(-,_t1,z,_t0)(+,_t0,y,_t1)(二,x,_t0)由于中間語言對后面

6、的代碼優化和目標代碼生成有密切關系,又和目標機器的體系結構有關,所以中間語言的選擇對于編譯器的效率和質量有很大的影響。1.4 代碼優化代碼優化是把中間代碼進行變換,以產生更加高效的目標代碼。1.5 目標代碼生成目標代碼生成是編譯最后一個階段,它把中間代碼轉換成匯編指令或可重定位的目標代碼。例如對于前面生成的中間代碼,可以產生舊MPC匯編指令為:movax,mmulax,10movbx,zsubbx,axaddbx,ymovx,bx匯編代碼經過Masm匯編器(Assembler)和連接器(Linker)處理,就產生了可在IBMPC機器上運行的二進制代碼。2 .形式語言簡介2.1 文法和語言文法是

7、產生語言的規則,它可定義為:對于一個四元式G=(Vn,Vt,S,P),其中(1) Vn是非終結符號的有限集合(2) Vt是終結符號的有限集合,且VtAVn二(3)開始符號S,SCVn(4) 一組產生式P,P中的每一個產生式都具有如下形式:uv,u(VnUVt)+且至少要有一個非終結符號,vC(VnUVt)*則G表示一個文法。喬姆斯基(NoamChmosky)把文法分成四類:0型文法又稱無約束文法,產生式的形式為a-b,a、b是任意字符串。1型文法又稱上下有關文法,產生式形式為a-b,且|aR|b|02型文法又稱上下文無關文法(Context-FreeGrammar),產生式形式為A-a,a(V

8、nUVt)*,ACVn。3型文法又稱正規文法,它的產生式左部是一個非終結符號,右部最多只有一個非終結符號且在右部的最左端或最右端。通常程序設計語言的文法屬于2型文法,可被下推機(PushdownAutomaton以別。語言定義為L(G尸wS=*w,wVt*,可見,文法G中的Vt相當于產生語言的字母表,G中的一組產生式是產生語言的一組規則;語言L(G)中的每一個句子w,是由G的開始符號S經推導得到的,完全由終結符號組成的字。非終結符號是引起推導繼續進行的中間符號,在推導進行到某一步時,如果再沒有非終結符號留在推導的結果中,則稱推導成功。在語言的設計和編譯器的編寫方面,文法都提供了極大的優點:a)

9、文法給出了精確的,也易于理解的語言語法說明。b)對于某些文法類,可以自動產生高效的分析器。額外的好處是,分析器的構造過程可以揭露出語法的二義性和其它難于分析的結構,這些問題在語言和它的編譯器的最初設計階很可能沒有發現。c)設計得漂亮的文法,把結構加于程序設計語言,這些結構對把源程序翻譯成為正確的目標代碼和錯誤診斷都是有用的。把以文法為基礎的翻譯的描述轉變成程序的開發工具也是存在的。d)語言也是逐漸完善的,需要補充新的結構和完成附加的任務。如果存在以文法為基礎的語言的實現,這些新結構的加入就更方便。2.2 巴科斯范式(BNF)巴科斯范式(BackusNormalForm,BNF)是描述語法規則的

10、一種形式方法,在該方法中,使用如下符號:非終結號:=定義符|或者括號內的成份可以重復出現多次,也可以不出現括號內的成份為任選項,可以出現一次或不出現例如C語言中IF-THEN語句可以表示成:IF語句:=IF布爾表達式THEN語句卜ELSE語句習用巴科斯范式的形式表示文法的優點是簡潔、清楚并容易被理解。3 .編譯程序的實現環境ParseGenerato徜介及其使用編譯器生成工具-ParseGenerator基于Windows平臺,它集成了詞法生成器ALEX和語法生成器AYACC,并提供了較為強大的類庫。其主要優點體現在以下幾個方面:可以視一個編譯程序為一個Project,集成Alex和Ayacc

11、文件的環境有利于整體調試和開發。且編輯界面友好,利于初學者使用。.l文件(lex文件)和.y文件(yacc文件)可生成為標準的C原代碼,也可生成VisualC+和BorlandC+格式的原代碼。這對習慣與BC或VC編程的程序員,無疑是極大的方便。ALex和AYacc的表驅動代碼隱藏在聯接庫中。庫在程序LINK的時候連入系統中。這在程序編譯的效率和靈活性兩個方面都有較大貢獻。ALex和AYacc的原代碼和和生成的目標代碼(C或C+)可以建立語句的對應,這對生成代碼的調試提供很大方便。實驗中的編譯程序采用將ALex和AYacc文件轉化為VisualC+格式的代碼。現將程序中使用的聯接庫中主要類和函

12、數作一介紹。類yylexer-所有詞法分析器類的基類yylexer類提供由Alex生成的C+詞法分析器的一切基本功能。yylexer是一個抽象類,要使用它,必須繼承出自己的類,并實現抽象函數yylex和yyaction。C-編譯器程序中的詞法分析器類是其子類C_Lexer類。類yyparser-所有語法分析器類的基類yyparser類提供由AYacc生成的C+語法分析器的一切基本功能。yyparser是一個抽象類,要使用它,必須繼承出自己的類,并實現抽象函數yywork和yyparseaction=C-編譯器程序中的語法分析器類是其子類C_Parser類。五.詳細設計1.功能說明輸入:類C語言

13、純文本源程序。輸出:目標機為具有8086+處理器的MSDOS系統下的二進制可執行代碼。PCAssemblyLanguage編語言源代碼以供分析使用。本編譯程序實現的主要功能如下表所示:功能備注支持以下數據類型:int整型char字符型char口字符數組int口整型數組整型為有符號16位數。字符型為8位數。數組的下標允許為任何合法的表達式。經過簡單引、充后,即可實現長整型,無符號整型。支持以下數據操作:+加法-減法*乘法/除法%取余+自力口1-自減1*乘力&,|位與,位或A異或位非&&,|邏輯與,邏輯或!邏輯非<,>,<=,>=關系比較運算=,!=

14、關系比較運算<<,>>算術移位+-*/%=,*=,多達12種賦值<<=,>>=,&=,語句尸,A=,=支持以關鍵子_asm前導的形式為_asm的嵌入匯編代碼(EMBEDEDASSEMBLY)對嵌入匯編的支持大大提高的諦言的可用性,一定程度彌補了系統函數較少的缺憾。提供系統級庫函數:voidprint(/*表達式*/,%t);支持字符串,字符,整型三種類型的變量輸出,包括任何合法表達式的值。支持循環,轉移,判斷分支的程序設計,支持if,if.else,if.elseif.forwhile,do.whilegoto.語句。支持Label,允許

15、在任何語句前定義Label作為控制轉移目的地。for和while語句支持break,continue流程控制。支持函數概念。系統以main函數為入口函數。支持源程序注釋。注釋以“/或"/*",標型支持出錯提示。對于嵌入匯編代碼的出錯提示可以通過重定向匯編代碼編譯器的出錯信息實現。2.詞法分析器(lexer)2. 1正規式和DFA e和小都是2上的正規式,它們所表示的正規集分別為e和小 任何aCE,a是2上的一個正規式,它所表示的正規集為a 假定U和V都是2上的正規式,它們所表示的正規集分別記為L(U)和L(V),那么,(U|V)、(U.V)和(U)*也都是正規式,它們所表示

16、的正規集分別為L(U)UL(V)、L(U)L(V)和(L(U)*。僅由有限次使用上述三步驟而定義的表達式才是2上的正規式,僅由這些正規所表示的字集才是2上的正規集。正規式可以有效地描述詞法,而確定的有限自動機(DFA)能準確地識別正規集,執行詞法分析的功能。2.2利用有限自動機進行詞法分析詞法分析是整個編譯過程的第一階段,它將字符序列轉化為單詞序列。識別單詞的基本方法是根據詞法定義構造有限自動機即描述語言結構特征的狀態轉換圖。例如對于十進制整數正規定義:1-9+0-9*可以構造如圖3所示的有限自動機。圖3識別十進制整數的有限自動機其中狀態2為接收態,若對于一個字符序列有限自動機可以到達2狀態,

17、則說明一個整數已被識別出來。詞法分析器構造程序LEX正是根據這一原理工作的。構造詞法分析器的主要任務是設計詞法的正規定義和相關的動作。上面例子的LEX程序段就是:1-9+0-9*returnICON;2. 3C-詞法分析器的實現數據結構1)關鍵字和系統標識符表Ktab保存關鍵字和系統標識符的信息,定義如下:typedefstructchar*name;intval;KWORD;其中name域保存關鍵字的名字,val域保存關鍵字的種類標識。val域就是詞法分析器傳遞給語法分析器的終結符信息。2) C-中的關鍵字以下為Ktab數組的定義:KWORDKtab="break",BR

18、EAK"char",TYPE"continue",CONTINUE,"do",DO,"else",ELSE,"for",FOR,"goto",GOTO,"if",IF,"int",TYPE,"main",MAIN,"print",PRINT,"while",WHILE;具體實現(參見源文件C-_lex.l)1)對注釋的處理:支持/*.*/和/兩種注釋風格,對于注釋內容在匹配到/

19、*和/后,直接通過動作input跳過。處理了注釋符號遺漏的情況,并有出錯信息顯示。2)常數的處理:詞法分析器可識別十進制、八進制和十六進制無符號整數以及字符常數(形為a;并通過函數intstoi(char*string,intradix)轉化成數值形式。3)標點符號的處理:直接返回其相應的標識。4)標識符的處理:識別標識符后,調用函數id_or_keyword查找其屬性值并返回。對于系統保留字和關鍵字,函數id_or_keyword返回相應的標識(token)返回值相同的,可以通過yytext區別。對于用戶自定義的標識符,函數id_or_keyword返回NAME。為了提高查找關鍵字和系統標識

20、符表的效率,函數id_or_keyword采用二分查找法(bsearch函數)。5)嵌入匯編(_asm)的處理:在函數id_or_keyword()中當遇到yytext="_asm”時,則進入嵌入匯編處理代碼:史匹而字符'',如果接下來的第一不字符不是',則打印出錯信息。如果匹配則將后續代碼原樣寫入匯編代碼中,直至遇到字符結束;如果未遇到則打印出錯信息。由于要防止嵌入匯編代碼中出現字符立即操作數'或注釋語句中的',因此要考慮這些情況。采用上述方法的好處是大大簡化了語法分析器的工作,不必設計大量的產生式來處理匯編格式。但是這樣就不能檢查嵌入匯編的

21、語法錯誤。可以采用這樣的方法:用Masm編譯嵌入的代碼,重定向其輸出而判斷有無匯編語法錯誤。6)生成的C_Lexer的類定義(參見源文件C-_lex.h):classC_Lexer:publicyyflexerpublic:嵌入C_Lexer();protected:voidyytables();virtualintyyaction(intaction);public:;C_Lexer()實現對詞法分析器對象的初始化,它調用yytables()。yyaction()則具體由定義的正則表達式實現歸約。3.語法分析器(parser)3.1上下文無關文法上下文無關文法G可以用一個四元組表示G=(V,

22、T,P,S)其中: V是文法的非終結符號集,每個非終結符號表示語言的一個語法變量; T是終結符號集,每個終結符號表示語言的一個基本符號,即詞匯; P是產生式集,文法用產生式定義每個非終結符號; S是V中的一個非終結符號,稱開始符號。文法的每個產生式由左、右兩部分組成,左部是一個非終結符號;右部是由零個或若干個終結符、非終結符組成的符號用。3. 2LR分析方法LR分析方法是自底向上進行語法分析,它的功能很強,適用于多種上下文無關方法。L是指從左向右掃描輸入申,R指的是按照最右推導的的逆過程進行歸約。LR分析法具有一些優點: 能用上下文無關文法描述的程序設計語言結構,都可以構造其LR分析器進行識別

23、。 LR分析法是具有一般性的無回溯移進歸約分析法,并且能有效地被實現。 能用LR分析器分析的文法類包含能用LL(1)分析器分析的全部文法類。 LR分析器在自左向右掃描輸入時,可以盡可能地發現語法錯誤。輸入圖4LR分析器圖4是LR分析器的結構示意。其中分析棧存放狀態和移進、歸約的文法符號:S0XlSl.Xm-lSm-lS0其中,Si表示狀態,Xi表示文法符號;在實現中,文法符號不必進分析棧。動作表中的項目ACTIONSm,ai表示當前輸入符號為a、棧頂狀態為Sm時,分析算法應執行的動作;若ACTIONSm,a=S,表示移進,然后棧頂狀態為i;rj表示用產生式j歸約;acc表示接收輸入申,err表

24、示語法錯誤。狀態轉換表中的項目GOTOSi,X表示歸約出非終結符號X之后,當前棧頂狀態為Si時,分析棧應轉換到的下一上狀態,即棧頂的新狀態。LR分析算法為:根據輸入符號a、棧頂狀態Sm和動作表項actionSm,a的值,決定當前分析應執行的動作;移進、歸約、接收或出錯;移進或歸約之后要根據動作表或狀態轉換表設置分析棧的狀態。可以把分析棧中的用和等待輸入的終結答號用看成是兩個分量,這兩個分量構成如下形式的二元組:(S0X1S1X2S2.XmSm,siai+1.an#)這個二元組結構表示右句型X1X2.Xmaa+1.an#假定當前分析棧的棧頂為狀態Sm,下一個輸入符號為ai,分析器的下一個動作由動

25、作表項actionSm,a決定。,如果actionSm,a=移進S,則分析器執行移進,二元組變成(S0XlSlX2S2.XmSmaiS,ai+1.an#)即分析器將輸入符號ai和狀態S移進棧,于是,a+1變成下一個輸入符號。 如果actionSm,a=歸約A-0則分析器執行歸約,二元組變成(S0XlSlX2S2.Xm-rSm-rAS,ci+1.an#)其中,S由goto表確定:S=gotoSm-r,a,r=|0|,是句柄號用的長度。歸約時,分析器先從棧中彈出2r個元素:r個狀態和r個文法符號;于是使狀態Sm-r出現在棧頂;然后,再把歸約產生式左部的非終結符A和由gotoSm-r,A確定的狀態S

26、壓入棧。在歸約過程中不改變輸入符號。對LR分析器來說,從棧中彈出的文法符號用Xm-r+1.Xm總是匹配歸約產生式的右部B。 如果actionSm,a=acc,則接收輸入符號用,語法分析完成 如果actionSm,a=err,則發現語法錯誤,調用錯誤處理子程序。3.3C-系統中使用的主要產生式(參見源文件C-_par.h)programMAINLPRPcompound_stmtcompound_stmtLClocal_defsstmt_listRClocal_defsdef_listdef_listdef_listdef|/*epsilon*/defspecifiersdecl_listSEMI

27、decl_listvar_decl|decl_listCOMMAvar_declvar_declnew_name|var_declLBICONRB|LPvar_declRPnew_nameNAMEspecifiersTYPEstmt_liststmt_liststatement|/*epsilon*/statementSEMI|compound_stmt|PRINTLPexprCOMMADIVOPICONRPSEMI|exprSEMI|GOTOtargetSEMI|targetCOLONstatement|IFLPtestRPstatement|IFLPtestRPstatementELSEs

28、tatement|WHILELPtestRPstatement|DOstatementWHILELPtestRPSEMI|FORLPopt_exprSEMItestSEMIopt_exprRPstatement|BREAKSEMI|CONTINUESEMItestexpr|/*epsilon*/targetNAMEopt_exprexprexprexprCOMMAnon_comma_exprnon_comma_exprEQUALnon_comma_expr|non_comma_exprASSIGNOPnon_comma_expr|or_expror_expr:or_listor_list:or

29、_listORORand_expr|and_exprand_expr:and_listand_list:and_listANDANDbinary|binarybinary:binaryRELOPbinary|binaryPOWERbinary|unaryunary:LPexprRP|3. 4系統中符號表的實現1)符號表的組織要求編譯程序用符號表跟蹤關于名稱的匯聚信息和作用域,當詞法分析器識別出一個標識符后,編譯程序就查找符號表,看它是否在符號表中,如果沒有,則把這個新標識符填入符號表。在語義分析階段和代碼生成階段也要通過查找符號表來獲得標識符的屬性信息。可見在編譯過程中符號表的查、填動作非常頻

30、繁,因而提高符號表查填效率是提高編譯程序運行效率的關鍵因素,也是對符號表設計的根本要求。2)符號表的幾種組織方式線性表符表項按順序排列,這種組織方式最簡單并且實現也很容易。線性表的缺點是插入和查找的效率較低,雖然可以采用反序查找、表項排序、動態調整表項來提高效率,但其性能的改善是很有限的。,哈希表通過計算符號的哈希值來確定其在表格中的位置。哈希表結構簡單、實現較容易,而且其插入和查找效率很高。采用哈希表要解決“沖突”的問題,而解決沖突將會提高哈希表的復雜度。二叉樹二叉樹的組織方式平均查填效率最高,但實現的復雜度較高。對于名稱沖突也要特別處理。在某些情況下,二叉樹會退化成線性表,這個問題可以通過

31、采用AVL樹的結構來解決,但這會進一步提高實現的代價。3)C-系統中符號表的組織(參見源文件Symbol.h)本編譯程序中對符號表的管理和操作在CSymbol類中實現,采用的是哈希雜湊表的方式。該類的聲明如下:classCSymbolpublic:CSymbol();symbol*NewSymbol(char*name,unsignedlevel);symbol*FindSymbol(char*name);boolDeleteNest(symbol*pHead);unsignedHash(char*name);virtual-CSymbol();private:Hash_Node*SymTab

32、leTABLE_LEN;類中所涉及到的結構聲明如下:structsymbol/輸入變量名/實際變量名/當前嵌套級/變量類型/指向同層的下一個變量charnameNAME_MAX+1;charrnameNAME_MAX+1;unsignedlevel;type*pType;symbol*next;structHash_NodeHash_Node*pre;Hash_Node*next;symbol*sym;/上一個沖突節點/下一個沖突節點/指向此節點上的變量CSymbol采用哈希表來實現對變量的管理和查找。變量表采用數組實現,對于每一個產生哈系沖突的變量節點,利用鏈表將其連接到已有的節點后。在本編

33、譯程序中,采用了較復雜的計算哈系值的算法,其偽碼如下:unsignedCSymbol:Hash(char*name)hash_val=0;for(制變量名中的每一個字符)hash_val=(hash_val<<2)+變量字符值;if(i=hash_val&0x3fff)hash_val=(hash_valA(i>>12)&0x3fff;返回hash_val;CSymbol類中兩個主要的成員函數是:symbol*FindSymbol(char*name),實現根據變量名,在變量表中查找該一項。-symbol*NewSymbol(char*name,unsi

34、gnedlevel),實現在變量表中力入個symbol項。4)其他主要結構定義(參見源文件structtypeunsignednoun;intnum_ele;intv_int;一Structs.h)/CHARINTnumberofelementsifarrayValueifconstantstructvaluecharnameNAME_MAX*2;type*pType;symbol*sym;boollvalue;boolis_tmp;unsignedoffset;/Operandthataccessesthevalue/Variable'stype/Originalsymbol/TRU

35、E=lvalue,FALSE=rvalue/TRUE=temp,FALSE=non-temp/Abolutevalueofoffsetfrombaseoftemp/stack;3. 5系統中局部變量的處理雖然本編譯程序采用預分配棧來存放局部變量,這樣的做法浪費空間且缺乏靈活性,但是它帶來的一個好處是局部變量可以回收,而不像很多編譯程序存在著局部變量無法回收的缺憾。處理局部變量的主要函數有(參見源文件Functions.h及Functions.cpp):voidfigure_local_offsets(symbol*s);voidrelease_local(symbol*s);函數巾gure_l

36、ocal_offsets為一個層中的局部變量分配空間,而函數release_local則釋放在某一層灰行疝寸釋放其中的所有變量。這可以通過遍歷雜湊鏈表中的該層一的變量鏈表(單向鏈表)得到所有變量的存儲總長度,然后把局部變量堆棧指針減掉這個長度就可以了。這樣該層的所有變量所占的空間都釋放掉了。下一次又可以使用這些釋放的空間。4. 6系統中臨時變量的處理臨時變量是編譯系統中使用較多的部分,通過建立臨時變量來記錄每一次運算的結果,使后續的運算能方便地引用前次的值,是一個較通用的方法。所以,臨時變量的管理成為編譯程序中一個比較重要的部分。因為本編譯程序的條件限制,系統中對臨時變量的處理采取棧式結構存放

37、的方法。存放臨時變量的堆棧是系統全局的,通過在編譯程序初始化是建立,如下:fprintf(OutPut,"t%stdbt%ddup(?)nn",TMP_STACK,TMP_STACK_LEN);此語句將在匯編源代碼中生成如下的語句:t_stackdb1024dup(?)系統通過一個布爾型數組對臨時變量棧進行管理。boolTmp_RegTMP_STACK_LEN;Tmp_Regoffset的值表示臨時變量棧中偏移量為offset的空間是否已被分配為臨時變量的存放。系統使用以下4個函數完成對臨時變量的管理:inttmp_a110c(intsize);value*tmp_create(type*t);voidtmp_free(intoffset,intsize);voidtmp_freeall(void);3.7系統中代碼的生成編譯程序中的翻譯的推導規則和每一個推導的相應動作,生成匯編源代碼。(詳見程序清單)主程序框架的生成通過函數voidInit(void)和voidEnd(void)完成。Init主要任務: 生成數據段、代碼段; 生成主程序的起始代碼; 返回地址入棧; 創建全局和系統堆棧; 初始化系統變量。End主要任務: 生成返回操作系

溫馨提示

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

評論

0/150

提交評論