編譯器設計中布林表示式和控制語句的後向填充是什麼?
執行語法制導翻譯的最簡單方法是使用兩遍。首先,為輸入構建語法樹,然後以深度優先的順序遍歷樹,完成定義中給出的翻譯。
在單遍生成布林表示式和控制流語句程式碼的主要問題是,在單遍過程中,我們無法理解在生成跳轉語句時控制應該跳轉到的標籤。它可以透過生成一系列分支語句來解決這個問題,這些語句的跳轉目標暫時未定義。
每個這樣的語句將被放在一個 goto 語句的記錄中,其中標籤將在確定適當標籤時填充。它可以稱這種後續的標籤填充為後向填充。
布林表示式的後向填充
它可以構建一個適合在自底向上解析期間生成布林表示式程式碼的翻譯方案。語法中的非終結符標記 M 會在適當的時候觸發一個語義動作,來獲取要建立的下一個指令的索引。語法如下:
B → B1|| MB2|B1&& MB2|! B1|(B1)|E1rel E2|True|False
M → ϵ
翻譯方案如下:
| B → B1|| MB2 | {backpatch (B1. falselist, M. instr); B.truelist = merge (B1.truelist, B2.truelist); B.falselist =B2.falselist;} |
| B → B1&& MB2 | {backpatch (B1. truelist, M. instr); B.truelist = B2.truelist; B.falselist = merge (B1. falselist, B2.falselist);} |
| B → ! B1 | { B.truelist = B1.falselist; B.falselist = B1.truelist;} |
| B → (B1) | { B.truelist = B1.truelist; B.falselist = B1.falselist;} |
| B → E1 rel E2 | { B.truelist = makelist(nextinstr); B.falselist = makelist(nextinstr + 1); append ('if' E1. addr relop E2. addr 'goto-'); append ('goto-');} |
| B → True | { B.truelist = makelist(nextinstr); append ('goto-');} |
| 𝐁 → 𝐅𝐚𝐥𝐬𝐞 | { B.falselist = makelist(nextinstr); append ('goto-');} |
| 𝐌 →∈ | {M.instr = nextinstr;} |
控制流語句
現在它可以使用後向填充在一遍中翻譯控制流語句。考慮以下語法生成的語句:
S → if (B)then S | if (B)then S else S |while (B)then do
S| begin L end |A;
L → L; S | S
這裡 S 表示語句,L 表示語句列表,A 表示賦值語句,B 表示布林表示式。應該還有其他產生式,包括
- 後向填充 104 到指令 102 後。
100− if x < 100 goto -
101− goto -
102− if x > 200 goto 104
103− goto -
104− if x! = y goto-
105− goto-
- 後向填充 102 到指令 101 後
100− if x < 100 goto -
101− goto 102
102− if y > 200 goto 104
103− goto -
104− if x! = y goto-
105− goto-
給出了產生式,但是,它足以說明用於翻譯控制流語句的技術。
資料結構
網路
關係資料庫管理系統
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP