首頁 > 後端開發 > Golang > 主體

嵌套句子

王林
發布: 2024-07-31 10:27:53
原創
658 人瀏覽過

Sentenças aninhadas

對於那些不遵循POJ(JVM 上的Pascal)的人來說,它是一個將子集 從Pascal 轉換為JASM 的編譯器( Java Assembly),以便我們可以使用JVM 作為執行環境。

在上一篇文章中,我們解決了一些重要的錯誤,特別是在程式集的生成。在這篇文章中,我們將討論如何正確產生嵌套句子的程序集

當我們為 JVM 進行編譯時,有必要詳細說明這個令人難以置信的虛擬機器的各個點的功能。因此,我多次詳細介紹 JVM 的內部功能及其一些指令(操作碼)。

情境

正確處理巢狀句子的必要功能之一是解析器中可能具有多個上下文。這是因為,如果 解析器 只假定一個上下文,則會產生 標籤 並跳轉的嵌套控制語句(如iffor whilerepeat) 將錯誤地產生跳轉尋址。

處理上下文有兩種方法,分別是:

  • 解析器遞迴
  • 堆疊上下文

通常我會使用遞迴解析器方法。然而,為了使用 ANTLR 實作遞歸解析器,由於 POJ 中語法的結構方式,需要將程式碼直接注入語法中,但不建議此方法。因此,我們選擇了堆疊上下文的方法。

由於已經有一個堆疊實作來監視解析器在JVM 中堆疊/取消堆疊的類型,為了不必為特定類型建立另一個堆疊,我們決定建立一個stack此PR 中的通用。除了稍後能夠利用此實作之外,我仍然可以重構舊程式碼並刪除現有的特定 stack.

在此提交中,解析器已更改為正確堆疊/取消堆疊函數上下文。基本上,在函數的 解析器 的開頭,上下文是堆疊的,而在最後,上下文是未堆疊的。

嵌套句子

ifforwhilerepeat 等控制語句可以正常運作。然而,如果有嵌套句子,POJ 不會儲存上下文,最終會錯誤地產生 labels 並跳轉。這裡和這裡討論了程式集的產生如何適用於這些控制語句。

對於下面的範例,其中包含嵌套在另一個 if 中的範例,POJ 錯誤地產生了 標籤 和必要的跳轉:

program NestedIfs;
begin
  if (1 > 2) then
    if (2 > 3 ) then
      writeln('1 > 2 and 2 > 3')
    else
      writeln('1 > 2 and 2 <= 3')
  else
    writeln('1 <= 2');
end.
登入後複製

這個錯誤是已知的,我選擇在解析器支援上下文時解決它。

在此提交中,建立了 LabelsContext 結構,其中包含以下 標籤:

  • Else:對於 ifelse;
  • 的情況是必需的
  • NextStatement:包含下一語句的標籤
  • IterationStart:表示測試 whilerepeatfor.
  • 情況下的重複結構。

為了驗證程序集的正確生成,創建了測試來驗證嵌套if's、嵌套repeat's、嵌套while以及for's 巢狀。此處建立測試是為了驗證在遞歸函數的情況下程序集的產生。此外,有必要更新所有現有測試的預期程序集。最後,在此 PR 中,解析器 已更新為使用新的上下文結構。

以下是這些變更的完整 PR。這裡我們有commit ,其中包含if 句子正確運行的更改,這裡commit 指的是repeat,這裡commit 指的是while,這裡commit 指的是for

後續步驟

在下一篇文章中我們將討論資料輸入。現在不久我們就完成了這個專案的目標之一:從標準輸入讀取一個數字併計算其階乘。

完整的專案程式碼

包含項目完整程式碼和文件的儲存庫位於此處。

以上是嵌套句子的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板