類C編譯器 C代碼實現


大三上學期做的一個小項目

類C編譯器   

源代碼和測試文件地址https://github.com/zxt1995/ttbox.git

 

總體框架: 讀入待編譯文件->語義分析並轉換為指令->按照指令進行棧操作->得出結果

 

拓展部分(個人負責內容 其他內容在代碼中有注釋)

完成內容

Do while循環

Switch case語句

Goto語句

循環中Breakcontinue的實現

補充基礎部分的短路計算

 

詞法分析(switch)

Switch語句加入關鍵字 SYM_SWITCH,SYM_CASE,SYM_DEFAULT ,SYM_BREAK

加入新的OPR操作 OPR_CMP 保留棧頂和次棧頂 次棧頂是switch后面的選擇表達式的結果值 棧頂為1(相等) 0(不相等)

語法分析(switch)

 

switch(expression)

begin

Case num1:

0跳轉 Statement(若最后無break);

Case num2:   JMP到下一個Statement開頭

0跳轉 Statement(若最后有break);

Case num3:

0跳轉 Statement;

Default:   JMP到結束

Statement;

end;

 

代碼分析(switch)

 

pl0.h中加入全局變量

statement中 加入

Switch語句正常檢測對應SYM 然后做一次表達式計算即可

switch語句的最后

要判斷是否出現default來給最后一個case決定跳轉位置

 

 

Case部分代碼如下 default類似

 

 

Break 等待回填

 

 

 

截圖示例(switch)

測試樣例如下

左邊是測試代碼 右邊是步驟

下面是結果 結果只計算了一開始i的賦值和p=30  j=40滿足switch的語法規則

(這里結果是每次參數賦值之后的結果 后面的測試結果類同,組內其他成員實現了print函數可以輸出特定的參數結果)

 

 

 

 

 

詞法分析(goto)

加入關鍵字SYM_GOTO

加入新的label(字符型2元數組)

 

語法分析(goto)

 

 

begin:

statement

jmp statement

goto: label1;

Statement

label2:

statement

Statement jmp

goto: label2;

statement

label1:

statement

end;

只要匹配到對應的label就無條件跳轉就可以

但是由於不知道對應的label是在哪里出現 所以要在block結束后再回填跳轉指令

 

代碼分析(goto)

首先在statementif(getsym()==SYM_IDENTI)中加入無法辨別的id將他判別為標識符

 

 

 

然后在statementif(getsym()==SYM_GOTO)中存入另一個label

 

 

 

 

最后在main函數的block之后進行字符串匹配就行

 

 

 

截圖示例(goto)

測試樣例如下

 

 

 

結果滿足goto語法

 

 

 

詞法分析(do while)

Statement中重寫SYM_DO

 

語法分析(do while)

 

do

Statement 0跳轉

while(expression);

 

代碼分析(do while)

基本實現方式和while循環類似

 

 

截圖示例(do while)

(continue break do while共同示例)

 

 

詞法分析(break continue)

 

加入關鍵字 SYM_BREAK

   SYM_CONTINUE

加入全局變量

 

 

每次進入循環的時候 loopfi++ 出循環的時候loopfi-- 這樣就不會在回填時出現失誤

(注回填指令在出循環之后馬上回填)

 

語法分析(break continue)

while循環為例(begin end總體歸約為一個大的statement)

 

 

 

 

 

 

 

 

While(expression)

begin

Statement  無條件跳轉到expression之前

Continue

Statement

break

Statement 無條件jmp到循環結束

Statement

End

 

代碼分析(break continue)

do while語句 for循環語句 while循環語句中都有修改 以while語句為例

 

 

 

添加識別sym   Breakcontinue如下

 

 

 

截圖示例(break continue )

附帶do while

 

 

 

結果正確

 

 

 

 

 

 

詞法分析(補充bool短路)

加入全局變量如下

加入和JPC相反的指令JNP不是0跳轉

 

語法分析(補充bool短路)

先以一層為例

Expression簡寫為expi JNP到結束

 

 

 

JPC到同層第一個||之后

   多層就存到對應層的的trur_listfalse_list然后結束代表括號之后的位置即可

 

代碼分析(補充bool短路)

如下以if語句為例

 

 

 

 

修改func_orfunc_and基本同上

or為例

 

 

遇到and更新假值鏈

遇到or更新真值鏈(同時填寫同層與上一層的假值出口)

遇到Not交換真值假值鏈內容

 

示例截圖

指令序列中不再出現opr_or opr_and

 

結果正確

 

 

總結(有什么能修改的地方)

Goto語句中label的數量

支持break continue的循環層數

Swich casecasebreak的數量 都有一定上限!!

有待更好的數據結構來表述而不是二維/一維數組

 

所有代碼https://github.com/zxt1995/ttbox.git

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM