#include #include #include #include "dbc.hpp" using namespace fmt; %%{ machine ansi_parser; action tstart { start = fpc; } action number { auto [ptr, ec] = std::from_chars(start, fpc, value); dbc::check(ec == std::errc(), "error in number parsing"); println("NUM: {}", value); } action color256 { println("COLOR256"); } action color24b { println("COLOR24B"); } action colorSingle { println("SINGLE"); } action colorBasic { println("BASIC"); } action bg { println("BG"); } action fg { println("FG"); } action any { println("ANY: {}:{}", int(fc), fc); } action start { println("START"); } action end { println("END"); } ESC = 0x1B; start = ESC "["; fg = "38;" %fg; bg = "48;" %bg; color256 = "5;" %color256; color24b = "2;" %color24b; num = (digit+) >tstart %number; ansi := |* start => start; (fg|bg) color256 num ";" num => { println("256 doit"); }; (fg|bg) color24b num ";" num ";" num => { println("24b doit"); }; num ";" num => colorBasic; num => colorSingle; "m" => { fgoto main; }; *|; main := (any @any -- ESC)* ESC @{ fhold; fgoto ansi; }; }%% %% write data; bool parse_ansi(std::string_view codes) { const char *start = NULL; int cs = 0; size_t value = 0; const char *p = codes.data(); const char *pe = p + codes.size(); const char *eof = pe; const char *ts = p; const char *te = p; int act = 0; %% write init; %% write exec; print("PROCESSED {} CHARS of {}", p - codes.data(), codes.size()); return true; }