#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace ztl{ namespace readFileToStrType{ struct CannotOpenFile{}; using ReturnType = std::variant< std::string, CannotOpenFile >; } inline readFileToStrType::ReturnType readFileToStr(const std::string_view &filePath){ std::ifstream ifs(filePath.data()); if(!ifs){ return readFileToStrType::CannotOpenFile{}; } std::string s(std::istreambuf_iterator(ifs),{}); return s; } #define ZTL_FOR_EACH ZTL_FOR_EACH_V(Keyword)\ ZTL_FOR_EACH_V(Identifier)\ ZTL_FOR_EACH_V(Literal)\ ZTL_FOR_EACH_V(Operator)\ ZTL_FOR_EACH_V(Separator)\ ZTL_FOR_EACH_V(Whitespace)\ #define ZTL_FOR_EACH_V(v)v, enum class TokenType{ ZTL_FOR_EACH }; #undef ZTL_FOR_EACH_V inline std::string getTokenTypeName(TokenType t){ switch (t) { #define ZTL_FOR_EACH_V(v)case TokenType::v:{return #v;} ZTL_FOR_EACH default: throw std::runtime_error("unknown TokenType"); } throw std::runtime_error("unreachable"); } #undef ZTL_FOR_EACH_V #undef ZTL_FOR_EACH struct Token{ TokenType type; std::string str; friend std::ostream&operator<<(std::ostream&os,const Token &t){ os<<"{ TokenType: "< tokens; Lexer(const std::string &s){ size_t line{1},lineStart{}; for(size_t i=0;i keywords = {"int","print"}; bool isKeywords = false; for(const std::string&k:keywords){ if(nstr==k){ isKeywords=true; break; } } if(isKeywords){ tokens.emplace_back(TokenType::Keyword,std::move(nstr)); }else{ tokens.emplace_back(TokenType::Identifier,std::move(nstr)); } }else if(s[i]=='\n'){ while(isspace(s[i+1])&&i+1