上回提到了如何新增一個 P4 Compiler 專案,但卻未在主程式(main.cpp)中新增任何相關的程式
這一偏要說明如何在 main 中產生 IR 並以 JSON 格式輸出 IR 內容。
Options
首先,P4 Frontend 在解析 P4 程式時需要載入相關的 Option,而 P4 Frontend 本身有提供一個可以擴充的 CompilerOption
類別,可透過以下方式定義:
#include "frontends/common/options.h"
class FTTOptions : public CompilerOptions {
public:
cstring outputFile = nullptr;
FTTOptions() {
registerOption("-o", "outfile",
[this](const char* arg) { this->outputFile = arg; return true; },
"Write output to outfile");
}
};
這邊定義了 outfile
這一個參數,讓使用者可以定義要輸出的檔案路徑。
CompilerOptions 內建的參數可以至 frontends/common/options.h
查詢。
接著需要以這一個 Option 類別去製作一個新的 CompilerContext
類別。
using FTTContext = P4CContextWithOptions;
最後是使用這一個 Context 去解析 main 的 argc 及 argv 初始化要編譯的 P4 檔案路徑。
int main(int argc, char *const argv[]) {
AutoCompileContext autoFTTContext(new FTTContext);
auto& options = FTTContext::get().options();
options.langVersion = CompilerOptions::FrontendVersion::P4_16;
options.compilerVersion = "0.0.1";
if (options.process(argc, argv) != nullptr)
options.setInputFile();
if (::errorCount() > 0)
return 1;
}
在 main 當中也可以直接指定好 options 中參數的預設內容,例如這一個 Compiler 預設是處理 P4-16 語言等等。
在 error.h
中也提供了常用的錯誤處理功能,例如從 ErrorReporter
中獲得目前錯誤的數量(::errorCount()
)等。
完成這部份之後,原則上執行 p4c-ftt
時就可以使用 --help
去看可以使用的參數了。
Parser & Frontend
在交由 Frontend 處理之前,需要由 P4 的 Parser 先處理好 P4 程式,使用方法如下:
#include "frontends/common/parseInput.h"
/* ... */
auto program = P4::parseP4File(options);
獲得 program 之後,將其帶入 Frontend 中處理:
#include "frontends/p4/frontend.h"
/* ... */
P4::FrontEnd fe;
program = fe.run(options, program);
這邊稍微題一下 P4::parseP4File
與 P4::FrontEnd
的差異。
基本上,第一步驟會透過 P4 Parser 去將 P4 程式轉換成 IR,而 FrontEnd 則是套用許多優化用的 Visitor 去處理已經 Parse 好的 IR。
Visitor 的部份之後會在用一篇文章說明原理以及使用方式。
產生好的 IR 可以透過 JSONGenerator
去產生 Json 格式的 IR。
#include
#include "lib/nullstream.h"
/* ... */
JSONGenerator(*openFile(options.dumpJsonFile, true), true) << program << std::endl;
之後可以透過輸出的 IR 範例程式來了解一個 P4 程式是如何被轉換成 IR 的。
本篇的程式一樣可以在這邊找到:
https://github.com/Yi-Tseng/p4c-ftt
Misc
原先想說本篇一同介紹一下如何撰寫 Midend,但後來發現可能要先把 IR 以及 Visitor 先講完比較容易了解 Midend 要如何撰寫,下兩篇預計會介紹 IR 以及 Visitor。