大三上學期做的一個小項目
類C編譯器
源代碼和測試文件地址https://github.com/zxt1995/ttbox.git
總體框架: 讀入待編譯文件->語義分析並轉換為指令->按照指令進行棧操作->得出結果
拓展部分(個人負責內容 其他內容在代碼中有注釋)
完成內容
Do while循環
Switch case語句
Goto語句
循環中Break和continue的實現
補充基礎部分的短路計算
詞法分析(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)
首先在statement的if(getsym()==SYM_IDENTI)中加入無法辨別的id將他判別為標識符
然后在statement的if(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 Break和continue如下
截圖示例(break continue )
附帶do while
結果正確
詞法分析(補充bool短路)
加入全局變量如下
加入和JPC相反的指令JNP不是0跳轉
語法分析(補充bool短路)
先以一層為例
Expression簡寫為expi JNP到結束
JPC到同層第一個||之后
多層就存到對應層的的trur_list和false_list然后結束代表括號之后的位置即可
代碼分析(補充bool短路)
如下以if語句為例
修改func_or和func_and基本同上
以or為例
遇到and更新假值鏈
遇到or更新真值鏈(同時填寫同層與上一層的假值出口)
遇到Not交換真值假值鏈內容
示例截圖
指令序列中不再出現opr_or 和opr_and
結果正確
總結(有什么能修改的地方)
Goto語句中label的數量
支持break continue的循環層數
Swich case中case和break的數量 都有一定上限!!
有待更好的數據結構來表述而不是二維/一維數組
所有代碼https://github.com/zxt1995/ttbox.git