mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-01 10:04:59 +01:00
Treesitter parser (#2902)
A push towards better editor support. See utils/treesitter/README.md --------- Co-authored-by: josh11b <josh11b@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <tree_sitter/api.h>
|
||||
#include <tree_sitter/parser.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
TSLanguage* tree_sitter_carbon();
|
||||
}
|
||||
|
||||
// Reads a file to string.
|
||||
static auto ReadFile(std::filesystem::path path) -> std::string {
|
||||
std::ifstream file(path);
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
file.close();
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
// TODO: use file_test.cpp
|
||||
auto main(int argc, char** argv) -> int {
|
||||
if (argc < 2) {
|
||||
std::cerr << "Usage: treesitter_carbon_tester <file>...\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
auto* parser = ts_parser_new();
|
||||
ts_parser_set_language(parser, tree_sitter_carbon());
|
||||
|
||||
std::vector<std::string> failed;
|
||||
std::vector<std::string> skipped;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string file_path = argv[i];
|
||||
std::string source = ReadFile(file_path);
|
||||
|
||||
// `and` in where clauses is not parsed correctly.
|
||||
// TODO: remove once where clause is implemented correctly.
|
||||
if (source.find("where") != std::string::npos &&
|
||||
source.find("and") != std::string::npos) {
|
||||
skipped.push_back(file_path);
|
||||
continue;
|
||||
}
|
||||
auto* tree =
|
||||
ts_parser_parse_string(parser, nullptr, source.data(), source.size());
|
||||
|
||||
auto root = ts_tree_root_node(tree);
|
||||
auto has_error = ts_node_has_error(root);
|
||||
char* node_debug = ts_node_string(root);
|
||||
|
||||
std::cout << file_path << ":\n" << node_debug << "\n";
|
||||
if (has_error) {
|
||||
failed.push_back(file_path);
|
||||
}
|
||||
|
||||
free(node_debug);
|
||||
ts_tree_delete(tree);
|
||||
}
|
||||
ts_parser_delete(parser);
|
||||
for (const auto& file : skipped) {
|
||||
std::cout << "SKIPPED " << file << "\n";
|
||||
}
|
||||
for (const auto& file : failed) {
|
||||
std::cout << "FAILED " << file << "\n";
|
||||
}
|
||||
if (!skipped.empty()) {
|
||||
std::cout << skipped.size() << " tests skipped.\n";
|
||||
}
|
||||
if (!failed.empty()) {
|
||||
std::cout << failed.size() << " tests failing.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user