簡體   English   中英

回補如何與標記一起使用?

[英]How does backpatching work with markers?

我在互聯網上搜索過,無法找到關於回調如何工作的正確解釋?

能否請您解釋一下回補是如何工作的? 它如何與標記一起使用

我知道它有兩種主要類型的標記:

  1. 有下一個四邊形
  2. 有下一個列表

我找到了這段代碼 ,他們在這段代碼中輸入一個輸入文件並使用RISKI語言創建一個文件。

在他們的第一次滾動中他們有:

PROGRAM : N FUNCTION M MAIN_FUNCTION

你可以看到N和M是標記(它們是空卷)。

一次性代碼生成在為條件生成代碼時存在一個小問題。 典型的if語句:

if CONDITION then ALTERNATIVE_1 else ALTERNATIVE_2

需要編譯成這樣的東西:

  compute CONDITION
  JUMP_IF_TRUE label1
  JUMP_IF_FALSE label2

label1:
  code for ALTERNATIVE_1
  JUMP label3

label2:
  code for ALTERNATIVE_2
  JUMP label3

label3:
  next statement

但是當生成CONDITION的代碼時,不知道label1label2在哪里,並且當生成ALTERNATIVE_1ALTERNATIVE_2的代碼時,不知道label3在哪里。

一種方法是使用符號名稱作為標簽,如上面的偽代碼,並在知道它們時填寫實際值。 這需要在跳轉語句中存儲符號名稱,這會使數據結構復雜化(特別是,您不能只使用二進制匯編程序代碼)。 它還需要第二次傳球,只是為了填補跳躍目標。

一種(可能)更簡單的方法是只記住跳轉語句的地址,並在知道目標地址時進行補丁。 這稱為“回調”,因為您返回並修補生成的代碼。

事實證明,在許多情況下,您最終會有多個分支到同一個標簽。 典型案例是“短路”布爾值,如C系列的&&|| 運營商。 例如,擴展原始示例:

if (CONDITION_1 and CONDITION_2) or CONDITION_3 then ALTERNATIVE_1 else ALTERNATIVE_2

  compute CONDITION_1
  JUMP_IF_TRUE label1
  JUMP_IF_FALSE label2

label1:
  compute CONDITION_2
  JUMP_IF_TRUE label3
  JUMP_IF_FALSE label2

label2:
  compute CONDITION_3
  JUMP_IF_TRUE label3
  JUMP_IF_FALSE label4

label3:
  code for ALTERNATIVE_1
  JUMP label5

label4:
  code for ALTERNATIVE_2
  JUMP label5

label5:
  next statement

事實證明,對於簡單語言,只需要記住兩個不完整的跳轉語句(通常稱為“true”和“false”)。 因為可能有多次跳轉到同一目標,所以這些跳轉實際上是不完整跳轉語句的鏈接列表,其中目標地址用於指向列表中的下一個跳轉。 因此,backpatching遍歷列表,修補正確的目標並使用原始目標查找需要修補的上一個語句。

你所謂的標記 (它是yacc / bison所稱的“中規則制作”的實例)並不與回調真正相關。 它們可用於多種用途。 在一次性代碼生成中,通常需要在規則中間執行某些操作,而回調只是一個示例。

例如,在假設的if語句中,有必要在解析CONDITION之前初始化backpatch列表,然后在THENELSE子句的開頭進行backpatch。 (另一個backpatch將在整個if語句的解析結束時觸發,但那個將在規則的finnal操作中。)

在規則中間執行操作的最簡單方法是插入中間規則操作,這相當於使用操作插入空的“標記”生成,如您指向的示例bison文件中所示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM