#include #include #include #include #include extern "C" { #include } extern "C" const TSLanguage* tree_sitter_tsf(void); #include "../../src/language/ast/deserializer.hpp" #include "./debug_printer.hpp" using namespace lsp::language::ast; // ==================== 文件读取 ==================== std::string ReadFile(const std::string& filepath) { std::ifstream file(filepath); if (!file.is_open()) { throw std::runtime_error("Cannot open file: " + filepath); } std::ostringstream oss; oss << file.rdbuf(); return oss.str(); } // ==================== Tree-Sitter 解析 ==================== class TreeSitterParser { public: TreeSitterParser() { parser_ = ts_parser_new(); if (!parser_) { throw std::runtime_error("Failed to create parser"); } // 设置语言 if (!ts_parser_set_language(parser_, tree_sitter_tsf())) { ts_parser_delete(parser_); throw std::runtime_error("Failed to set language"); } } ~TreeSitterParser() { if (tree_) { ts_tree_delete(tree_); } if (parser_) { ts_parser_delete(parser_); } } TSTree* Parse(const std::string& source) { if (tree_) { ts_tree_delete(tree_); tree_ = nullptr; } tree_ = ts_parser_parse_string( parser_, nullptr, source.c_str(), source.length()); if (!tree_) { throw std::runtime_error("Failed to parse source"); } return tree_; } TSNode GetRootNode() { if (!tree_) { throw std::runtime_error("No tree available"); } return ts_tree_root_node(tree_); } private: TSParser* parser_ = nullptr; TSTree* tree_ = nullptr; }; // ==================== 主程序 ==================== void PrintUsage(const char* program_name) { std::cout << "Usage: " << program_name << " [options]\n"; std::cout << "\nOptions:\n"; std::cout << " -v, --verbose Show verbose output with source code\n"; std::cout << " -c, --compact Use compact output mode\n"; std::cout << " -s, --show-source Show source code snippets (default: off)\n"; std::cout << " -l, --hide-location Hide location information\n"; std::cout << " -n, --no-colors Disable colored output\n"; std::cout << " -t, --no-tree Disable tree characters\n"; std::cout << " -k, --show-kind Show node kind enums\n"; std::cout << " -i, --incremental Test incremental parsing\n"; std::cout << " -h, --help Show this help message\n"; std::cout << "\nPreset Modes:\n"; std::cout << " --verbose Equivalent to: -s -k\n"; std::cout << " --compact Equivalent to: -c -l -t\n"; std::cout << "\nExamples:\n"; std::cout << " " << program_name << " test.tsf\n"; std::cout << " " << program_name << " test.tsf --verbose\n"; std::cout << " " << program_name << " test.tsf --compact\n"; std::cout << " " << program_name << " test.tsf -s -n # Show source without colors\n"; } int main(int argc, char* argv[]) { if (argc < 2) { PrintUsage(argv[0]); return 1; } std::string filepath; bool test_incremental = false; // 默认打印选项 debug::PrintOptions opts = debug::PrintOptions::Default(); // 解析命令行参数 for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "-h" || arg == "--help") { PrintUsage(argv[0]); return 0; } else if (arg == "-v" || arg == "--verbose") { opts = debug::PrintOptions::Verbose(); } else if (arg == "-c" || arg == "--compact") { opts = debug::PrintOptions::Compact(); } else if (arg == "-s" || arg == "--show-source") { opts.show_source_code = true; } else if (arg == "-l" || arg == "--hide-location") { opts.show_location = false; } else if (arg == "-n" || arg == "--no-colors") { opts.use_colors = false; } else if (arg == "-t" || arg == "--no-tree") { opts.use_tree_chars = false; } else if (arg == "-k" || arg == "--show-kind") { opts.show_node_kind = true; } else if (arg == "-i" || arg == "--incremental") { test_incremental = true; } else if (filepath.empty()) { filepath = arg; } else { std::cerr << "Unknown argument: " << arg << "\n"; return 1; } } try { // 读取文件 std::cout << "Reading file: " << filepath << "\n"; std::string source = ReadFile(filepath); std::cout << "File size: " << source.length() << " bytes\n\n"; // 创建 Tree-Sitter 解析器 TreeSitterParser ts_parser; [[maybe_unused]]TSTree* tree = ts_parser.Parse(source); TSNode root = ts_parser.GetRootNode(); // 创建 AST 反序列化器 Deserializer deserializer; ParseResult result; if (test_incremental) { std::cout << "Using incremental parsing...\n\n"; auto inc_result = deserializer.ParseIncremental(root, source); result = std::move(inc_result.result); std::cout << "Incremental Parse Statistics:\n"; std::cout << " Nodes parsed: " << inc_result.nodes_parsed << "\n"; std::cout << " Nodes unchanged: " << inc_result.nodes_unchanged << "\n"; std::cout << " Total nodes: " << inc_result.TotalNodes() << "\n"; std::cout << " Change rate: " << (inc_result.ChangeRate() * 100) << "%\n\n"; } else { result = deserializer.Parse(root, source); } // 打印 AST 结果(带源码) DebugPrint(result, source, opts); // 打印摘要 std::cout << "\n"; std::cout << debug::Color::BrightBlue << "========================================\n" << debug::Color::Reset; std::cout << debug::Color::BrightCyan << "Summary:\n" << debug::Color::Reset; std::cout << " File: " << filepath << "\n"; std::cout << " Size: " << source.length() << " bytes\n"; if (result.root) { std::cout << " Statements: " << result.root->statements.size() << "\n"; } std::cout << " Errors: "; if (result.HasErrors()) { std::cout << debug::Color::BrightRed << result.errors.size() << " ✗" << debug::Color::Reset << "\n"; std::cout << " Status: " << debug::Color::BrightRed << "FAILED" << debug::Color::Reset << "\n"; return 1; } else { std::cout << debug::Color::BrightGreen << "0 ✓" << debug::Color::Reset << "\n"; std::cout << " Status: " << debug::Color::BrightGreen << "SUCCESS" << debug::Color::Reset << "\n"; return 0; } } catch (const std::exception& e) { std::cerr << debug::Color::BrightRed << "Error: " << e.what() << debug::Color::Reset << "\n"; return 1; } }