LLVM 學習

今天+第二天早上完成了
https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.html
https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html

儅我表面上明白了詞法分析與語法分析,寫出來的的代碼卻非常混亂。

思考了一下,發現我非常容易疏忽于什麽時候應該gettok異常處理,解析后有問題的地方應該返回nullptr應該用什麽樣的代碼處理產生式

最後寫出來代碼還是和提供的代碼沒什麽差別,在某些地方對字符串的解析并不完全。

貼一下我認爲非常精妙的代碼

// Parse oprhs::(op primary)*
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
    while (true) {
        auto TokPrec = GetTokenPrecedence();
        if (TokPrec < ExprPrec) 
            return LHS;
        
        char BinOp = CurTok;
        getNextToken();

        auto RHS = ParsePrimary();
        if (!RHS) 
            return nullptr;

        auto NextPrec = GetTokenPrecedence();
        if (TokPrec < NextPrec) {
            RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
            if (!RHS) {
                return nullptr;
            }
        }
        LHS = std::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
    }
}
// Parse expression::primary oprhs
static std::unique_ptr<ExprAST> ParseExpression() {
    auto LHS = ParsePrimary();
    if (!LHS) {
        return nullptr;
    }
    return ParseBinOpRHS(0, std::move(LHS));
}

ExprPrec 的復用,既可以檢測是否表達式到達末尾,又可以檢測下一個運算符優先級是否比當前的優先級高。當遇到優先級較高的運算符后,我們可以通過對遞歸地對 RHS 處理,遇到稍低於高優先級的表達式的時候返回這個 RHS,從而實現最左推導。否則直接把整個 RHS 處理完就違背了 自頂向下的 LL(1) 的原則了。

明天將進入激動人心的 LLVM-IR