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})
*/