Skip to content

Instantly share code, notes, and snippets.

@genbtc
Created March 3, 2025 18:39
Show Gist options
  • Save genbtc/6dae803c34aca3e61459c7c63dc92c27 to your computer and use it in GitHub Desktop.
Save genbtc/6dae803c34aca3e61459c7c63dc92c27 to your computer and use it in GitHub Desktop.
GPT-contents-parser-FUSION.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix/phoenix.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
struct DirEntry {
std::string path;
};
struct ObjEntry {
std::string path;
std::string digest;
long mtime;
};
struct SymEntry {
std::string path;
std::string target;
long mtime;
};
BOOST_FUSION_ADAPT_STRUCT(DirEntry, path)
BOOST_FUSION_ADAPT_STRUCT(ObjEntry, path, digest, mtime)
BOOST_FUSION_ADAPT_STRUCT(SymEntry, path, target, mtime)
using ContentEntry = boost::variant<DirEntry, ObjEntry, SymEntry>;
template <typename Iterator>
struct DirParser : qi::grammar<Iterator, DirEntry(), ascii::space_type> {
DirParser() : DirParser::base_type(start) {
start %= qi::lit("dir") >> qi::lexeme[+(qi::char_ - qi::space)];
}
qi::rule<Iterator, DirEntry(), ascii::space_type> start;
};
template <typename Iterator>
struct ObjParser : qi::grammar<Iterator, ObjEntry(), ascii::space_type> {
ObjParser() : ObjParser::base_type(start) {
start %= qi::lit("obj") >> qi::lexeme[+(qi::char_ - qi::space)] >> qi::lexeme[+(qi::char_ - qi::space)] >> qi::long_;
}
qi::rule<Iterator, ObjEntry(), ascii::space_type> start;
};
template <typename Iterator>
struct SymParser : qi::grammar<Iterator, SymEntry(), ascii::space_type> {
SymParser() : SymParser::base_type(start) {
start %= qi::lit("sym") >> qi::lexeme[+(qi::char_ - ' ')] >> "->" >> qi::lexeme[+(qi::char_ - qi::space)] >> qi::long_;
}
qi::rule<Iterator, SymEntry(), ascii::space_type> start;
};
void parse_line(const std::string& line) {
using It = std::string::const_iterator;
DirParser<It> dir_parser;
ObjParser<It> obj_parser;
SymParser<It> sym_parser;
It iter = line.begin(), end = line.end();
DirEntry dir_entry;
if (qi::phrase_parse(iter, end, dir_parser, ascii::space, dir_entry)) {
std::cout << "[DIR] Path: " << dir_entry.path << '\n';
return;
}
ObjEntry obj_entry;
if (qi::phrase_parse(iter, end, obj_parser, ascii::space, obj_entry)) {
std::cout << "[OBJ] Path: " << obj_entry.path << ", Digest: " << obj_entry.digest << ", Mtime: " << obj_entry.mtime << '\n';
return;
}
SymEntry sym_entry;
if (qi::phrase_parse(iter, end, sym_parser, ascii::space, sym_entry)) {
std::cout << "[SYM] Path: " << sym_entry.path << ", Target: " << sym_entry.target << ", Mtime: " << sym_entry.mtime << '\n';
return;
}
std::cerr << "Failed to parse line: " << line << '\n';
}
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <filename>" << std::endl;
return 1;
}
std::ifstream file(argv[1]);
if (!file.is_open()) {
std::cerr << "Could not open file: " << argv[1] << std::endl;
return 1;
}
std::string line;
while (std::getline(file, line)) {
if (line.empty()) continue;
parse_line(line);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment