From 65bc64886084cda49eb4591c9973985dea345b81 Mon Sep 17 00:00:00 2001 From: Zengtudor Date: Sat, 12 Jul 2025 10:56:58 +0800 Subject: [PATCH] update --- include/Lexer.hpp | 106 +++++++++++++++++++++++++++++++++++++++++++--- include/Tools.hpp | 45 +++++++++++++++----- tests/test.cpp | 8 +++- 3 files changed, 141 insertions(+), 18 deletions(-) diff --git a/include/Lexer.hpp b/include/Lexer.hpp index acc992e..fabd3dc 100644 --- a/include/Lexer.hpp +++ b/include/Lexer.hpp @@ -1,30 +1,58 @@ #pragma once -#include #include -#include #include +#include +#include #include #include -#include +#include #include -#include "Lexer.hpp" +#include #include "Tools.hpp" namespace ztl{ namespace lexer{ - struct Token{std::string data;}; + inline std::string demangle(const char* mangled_name) { + int status = 0; + // 调用 __cxa_demangle 解 mangling + char* demangled = abi::__cxa_demangle( + mangled_name, + nullptr, // 输出缓冲区(nullptr 表示自动分配) + nullptr, // 缓冲区大小(nullptr 表示自动计算) + &status // 输出状态(0 表示成功) + ); + + // 用智能指针管理动态分配的内存,避免泄漏 + std::unique_ptr demangled_ptr(demangled, std::free); + + if (status == 0) { + return std::string(demangled_ptr.get()); // 解 mangling 成功 + } else { + return std::string(mangled_name); // 失败时返回原始名称 + } + } + struct Token{ + std::string data; + // std::string got_token_type() const { + // return demangle(typeid(*this).name()); + // } + }; struct Keywords:Token{}; struct Identifiers:Token{}; struct Literals:Token{}; struct Operators:Token{}; struct Separators:Token{}; struct Comments:Token{}; + struct EndSeparators:Token{}; struct EOF_Token:Token{}; + const std::vector white_spaces{'\n','\t',' '}; + const std::vector symbols{'(',')','"'}; + struct CharProvider{ std::string buffer; - std::vector white_spaces{'\n','\t',' '}; + size_t idx=0; Result peek(){ if (idx(Err("don't hava any string")); } - return Result(buffer.substr(start_idx,idx-start_idx+1)); + idx++; + return Result(buffer.substr(start_idx,idx-start_idx-1)); } void skip_whitespace(){ while(1) { @@ -96,6 +125,17 @@ namespace ztl{ inline bool is_alphanumeric(char c){ return is_digit(c) || is_alpha(c); } + + inline bool is_symbol(char c){ + bool is_symbol = false; + for(char i:symbols){ + if(c==i){ + is_symbol=true; + break; + } + } + return is_symbol; + } inline std::vector lexer(const std::string&s){ CharProvider cp(s); @@ -106,6 +146,30 @@ namespace ztl{ match(cp.peek(),[&cp,&tokens](char c){ if (is_alpha(c)){ tokens.push_back(Keywords{cp.consume_until(is_alphanumeric).unwrap()}); + }else if(c=='('){ + tokens.push_back(Separators{std::string()+cp.consume().unwrap()}); + match(cp.match(')'),[&cp](bool matched){ + if(!matched){ + throw std::runtime_error("unmatched '('"); + } + },[](const Err &e){ + throw std::runtime_error(e); + }); + }else if(c=='"'){ + cp.consume().unwrap(); + tokens.push_back(Literals{cp.consume_until([](char c)->bool{return c!='"';}).unwrap()}); + match(cp.match('"'),[&cp](bool matched){ + if(!matched){ + throw std::runtime_error("unmatched '\"'"); + } + },[](const Err &e){ + throw std::runtime_error(e); + }); + }else if(c==';'){ + tokens.push_back(EndSeparators{std::string()+cp.consume().unwrap()}); + } + else{ + throw std::runtime_error(std::string("unknown token named :'")+c+"'"); } },[&should_break](const Err &e){ should_break=true; @@ -115,4 +179,32 @@ namespace ztl{ return tokens; } } + +} + +namespace std { + template + concept DerivedFromToken = std::is_base_of_v; + + template + std::ostream&operator<<(std::ostream &os, const T &t){ + string name = ztl::get_T_name(); + // ztl::logger(ztl::demangle(typeid(t).name())); + // string name = ztl::demangle(typeid(t).name()); + return os< + std::ostream&operator<<(std::ostream &os, const std::vector &v){ + os<<"std::vector<"<()<<"> "<<"{"; + if(v.size()>0){ + for(size_t i=0;i #include #include #include #include #include - +#include namespace ztl{ + template + void logger(Ts&&...v){ + #ifndef NDEBUG + std::cout<<"log["; + (std::cout<<...< + std::string get_type_detail(){ + return __PRETTY_FUNCTION__; + } + + template + std::string get_T_name(){ + std::string type_detail = get_type_detail(); + // logger(type_detail); + size_t start = type_detail.find("T = "); + if(start == std::string::npos) { + throw std::runtime_error("Failed to get type name"); + } + size_t end = type_detail.find(';', start); + if(end == std::string::npos) { + end = type_detail.size()-1; + } + // logger(type_detail.substr(start + 4, end - start - 4)); + return type_detail.substr(start + 4, end - start - 4); + } + template struct overloaded:Ts...{using Ts::operator()...;}; @@ -44,12 +76,5 @@ namespace ztl{ } }; - template - void logger(Ts&&...v){ - #ifndef NDEBUG - std::cout<<"log["; - (std::cout<<...< #include +#include #define NV(v) {std::cout<<#v<<" : '"<<(v)<<"'\n";} + + int main(){ + ztl::get_T_name(); std::string hello_world = R"( print("hello ztl!"); )"; std::cout<<"This is a ztl's test\n"; NV(hello_world) - ztl::lexer::lexer(hello_world); + std::vector lexer_hello_world = ztl::lexer::lexer(hello_world); + ztl::logger(lexer_hello_world); } \ No newline at end of file