LLVM-编译器结构

一:前端

cpp 复制代码
#include <iostream>
#include <algorithm>
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"

class Lexer;

class Token{
    friend class Lexer;
public:
    enum TokenKind: unsigned short{
        eoi, //end of input
        unknown, //error of input
        ident, //[a-zA-Z]
        number,//[0-9]
        comma, //,
        colon, //:
        plus, //+
        minus, //-
        start, //'*'
        slash, //'/'
        l_paren, //'('
        r_paren, //')'
        KW_with, //with
    };
private:
    TokenKind  Kind;
    llvm::StringRef Text;
public:
    TokenKind getKind() const {return Kind; }
    llvm::StringRef getText() const {return Text; }

    bool is(TokenKind K) const {return Kind ==K; }
    bool isOneOf(TokenKind K1, TokenKind K2) const {return is(K1) || is(K2); }
    template<typename... Ts> 
    bool isOneOf(TokenKind K1, TokenKind K2, Ts... Ks) const { return is(K1)||isOneof(K2, Ks...);}
};

class Lexer{
    const char *BufferStart;
    const char *BufferPtr;

public:
    Lexer(const llvm::StringRef &Buffer) {
        BufferStart = Buffer.begin();
        BufferPtr = BufferStart;
    }

    void next(Token &token){
        while(*BufferPtr != '\0' && std::iswspace(*BufferPtr))
        {
            ++BufferPtr;
        }

        if(!*BufferPtr){
            token.Kind = Token::eoi;
            return;
        }

        if(std::isalpha(*BufferPtr))
        {
            const char *end = BufferPtr + 1;
            while(std::isalpha(*end))
            {
                ++end;
            }
            llvm::StringRef Name(BufferPtr, end - BufferPtr);
            Token::TokenKind kind = Name == "with" ? Token::KW_with : Token::ident;
            fromToken(token, end, kind);
            return;
        }
        else if (std::isdigit(*BufferPtr))
        {
            const char *end = BufferPtr + 1;
            while(std::isdigit(*end))
            {
                ++end;
            }
            fromToken(token, end, Token::number);
            return;
        }
        else {
            switch(*BufferPtr)
            {
                case ',': token.Kind = Token::comma; break;
                case ':': token.Kind = Token::colon; break;
                case '+': token.Kind = Token::plus; break;
                case '-': token.Kind = Token::minus; break;
                case '*': token.Kind = Token::start; break;
                case '/': token.Kind = Token::slash; break;
                case '(': token.Kind = Token::l_paren; break;
                case ')': token.Kind = Token::r_paren; break;
                default: token.Kind = Token::unknown; break;
            }
            fromToken(token, BufferPtr + 1, token.Kind);
            return;
        }
    
        

    }
private:
    void fromToken(Token &Result, const char *TokenEnd, Token::TokenKind Kind)
    {
        Result.Kind = Kind;
        Result.Text = llvm::StringRef(BufferPtr, TokenEnd - BufferPtr);
        BufferPtr = TokenEnd;
    }
};


int main()
{
    /*
        with a, b: a * (4 + b)

        with a: a * 3
    */
    std::cout << "Welcome to the " << __FILE__ <<std::endl;
}

//CMakeLists.txt 
/*
cmake_minimum_required(VERSION 3.16.0)

set(NAME "learn_llvm")
project(${NAME})

set(CMAKE_CXX_STANDARD 20) # this does nothing for MSVC, use target_compile_options below
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_BUILD_TYPE Debug)


find_package(LLVM REQUIRED CONFIG)

message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

# Set your project compile flags.
# E.g. if using the C++ header files
# you will need to enable C++11 support
# for your compiler.

include_directories(${LLVM_INCLUDE_DIRS})
message(STATUS ${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})

# Now build our tools
set(SOURCE main.cpp)
add_executable(${NAME} ${SOURCE})

# Find the libraries that correspond to the LLVM components
# that we wish to use
llvm_map_components_to_libnames(llvm_libs support core irreader)

# Link against LLVM libraries
target_link_libraries(${NAME} ${llvm_libs})
*/

二:中端

三:后端

相关推荐
Eloudy14 天前
hipcc 编译 amd gpu kernel 和 打包与解包的流程实验
编译器·llvm·gpu-arch
Eloudy1 个月前
^^ c++ 当然就是整个计算机科学
c++·算法·编译器·llvm·二进制分析
华为云开发者联盟1 个月前
LLVM技术在GaussDB等数据库中的应用
llvm·华为云gaussdb·华为云开发者联盟
高铭杰1 个月前
Postgresql源码(130)ExecInterpExpr转换为IR的流程
数据库·postgresql·jit·llvm·ir
Eloudy3 个月前
编译amd 的 amdgpu 编译器
开发语言·gpu·llvm
这个人中暑了3 个月前
如何调试Clang源码
调试·clang·lldb·llvm
Eloudy3 个月前
clang-query 的编译安装与使用示例
编译器·llvm
HATTERLONG4 个月前
一,Windows 下通过 CMAKE 搭建 LLVM 环境
llvm
HATTERLONG4 个月前
四,Clang ASTMatcher基础学习-CSDN博客
llvm