This commit is contained in:
csh 2025-10-25 23:52:33 +08:00
parent 857ba73755
commit e0e8c7b26d
10 changed files with 72 additions and 50 deletions

View File

@ -1,3 +1,4 @@
#include <iostream>
#include "./detail.hpp" #include "./detail.hpp"
#include "./tree_sitter_utils.hpp" #include "./tree_sitter_utils.hpp"
#include "./deserializer.hpp" #include "./deserializer.hpp"
@ -17,6 +18,10 @@ namespace lsp::language::ast
detail::ParseContext ctx(source, result.errors); detail::ParseContext ctx(source, result.errors);
auto program = std::make_unique<Program>();
program->location = ts::NodeLocation(root);
program->node_type_name = "program";
uint32_t count = ts_node_child_count(root); uint32_t count = ts_node_child_count(root);
for (uint32_t i = 0; i < count; i++) for (uint32_t i = 0; i < count; i++)
{ {
@ -26,10 +31,11 @@ namespace lsp::language::ast
if (!ts_node_is_named(child)) if (!ts_node_is_named(child))
continue; continue;
StatementPtr stmt = detail::ParseStatement(child, ctx); StatementPtr stmt = detail::ParseStatement(child, ctx);
if (stmt) if (stmt)
result.statements.push_back(std::move(stmt)); program->statements.push_back(std::move(stmt));
} }
result.root = std::move(program);
// 收集语法错误 // 收集语法错误
auto syntax_errors = detail::CollectSyntaxErrors(root, source); auto syntax_errors = detail::CollectSyntaxErrors(root, source);
@ -46,6 +52,10 @@ namespace lsp::language::ast
detail::ParseContext ctx(source, result.result.errors); detail::ParseContext ctx(source, result.result.errors);
auto program = std::make_unique<Program>();
program->location = ts::NodeLocation(root);
program->node_type_name = "program";
uint32_t count = ts_node_child_count(root); uint32_t count = ts_node_child_count(root);
for (uint32_t i = 0; i < count; i++) for (uint32_t i = 0; i < count; i++)
{ {
@ -62,7 +72,7 @@ namespace lsp::language::ast
StatementPtr stmt = detail::ParseStatement(child, ctx); StatementPtr stmt = detail::ParseStatement(child, ctx);
if (stmt) if (stmt)
result.result.statements.push_back(std::move(stmt)); program->statements.push_back(std::move(stmt));
} }
auto syntax_errors = detail::CollectSyntaxErrors(root, source); auto syntax_errors = detail::CollectSyntaxErrors(root, source);

View File

@ -46,7 +46,7 @@ namespace lsp::language::ast
// ===== 解析结果 ===== // ===== 解析结果 =====
struct ParseResult struct ParseResult
{ {
std::vector<StatementPtr> statements; std::unique_ptr<Program> root;
std::vector<ParseError> errors; std::vector<ParseError> errors;
bool HasErrors() const { return !errors.empty(); } bool HasErrors() const { return !errors.empty(); }

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <mutex> #include <mutex>
#include "../../utils/string.hpp" #include "../../utils/string.hpp"
#include "./tree_sitter_utils.hpp" #include "./tree_sitter_utils.hpp"
@ -207,7 +206,7 @@ namespace lsp::language::ast::detail
return type == "ERROR" || type == "MISSING"; return type == "ERROR" || type == "MISSING";
} }
std::vector<ParseError> CollectSyntaxErrors(TSNode node, const std::string& source) std::vector<ParseError> CollectSyntaxErrors(TSNode node, std::string_view source)
{ {
std::vector<ParseError> errors; std::vector<ParseError> errors;
@ -1715,7 +1714,7 @@ namespace lsp::language::ast::detail
return stmt; return stmt;
} }
StatementPtr ParseUsesStatement(TSNode node, [[maybe_unused]] ParseContext& ctx) StatementPtr ParseUsesStatement(TSNode node, ParseContext& ctx)
{ {
Location loc = ts::NodeLocation(node); Location loc = ts::NodeLocation(node);
@ -1728,11 +1727,11 @@ namespace lsp::language::ast::detail
for (uint32_t i = 0; i < count; i++) for (uint32_t i = 0; i < count; i++)
{ {
const char* field = ts_node_field_name_for_child(node, i); const char* field = ts_node_field_name_for_child(node, i);
if (!field || std::string_view(field) != "module") if (!field || std::string_view(field) != "units")
continue; continue;
TSNode child = ts_node_child(node, i); TSNode child = ts_node_child(node, i);
uses->modules.push_back(std::move(ts::Text(child, ctx.Source()))); uses->units.push_back(std::move(ts::Text(child, ctx.Source())));
} }
return uses; return uses;
} }

View File

@ -122,7 +122,7 @@ namespace lsp::language::ast::detail
// ===== 基础辅助函数 ===== // ===== 基础辅助函数 =====
TSNode FindChildByType(TSNode parent, const std::string& type); TSNode FindChildByType(TSNode parent, const std::string& type);
bool IsSyntaxErrorNode(TSNode node); bool IsSyntaxErrorNode(TSNode node);
std::vector<ParseError> CollectSyntaxErrors(TSNode node, const std::string& source); std::vector<ParseError> CollectSyntaxErrors(TSNode node, std::string_view source);
// 访问修饰符和方法修饰符解析 // 访问修饰符和方法修饰符解析
AccessModifier ParseAccessModifier(TSNode node, ParseContext& ctx); AccessModifier ParseAccessModifier(TSNode node, ParseContext& ctx);

View File

@ -2,7 +2,7 @@
namespace lsp::language::ast::ts namespace lsp::language::ast::ts
{ {
std::string Text(TSNode node, const std::string& source) std::string Text(TSNode node, std::string_view source)
{ {
uint32_t start = ts_node_start_byte(node); uint32_t start = ts_node_start_byte(node);
uint32_t end = ts_node_end_byte(node); uint32_t end = ts_node_end_byte(node);
@ -10,7 +10,7 @@ namespace lsp::language::ast::ts
if (start >= end || end > source.length()) if (start >= end || end > source.length())
return ""; return "";
return source.substr(start, end - start); return std::string(source.substr(start, end - start));
} }
Location NodeLocation(TSNode node) Location NodeLocation(TSNode node)

View File

@ -8,7 +8,7 @@ extern "C" {
namespace lsp::language::ast::ts namespace lsp::language::ast::ts
{ {
std::string Text(TSNode node, const std::string& source); std::string Text(TSNode node, std::string_view source);
Location NodeLocation(TSNode node); Location NodeLocation(TSNode node);

View File

@ -23,6 +23,7 @@ namespace lsp::language::ast
// ===== 节点类型枚举 ===== // ===== 节点类型枚举 =====
enum class NodeKind enum class NodeKind
{ {
kProgram,
// Expressions // Expressions
kIdentifier, kIdentifier,
kLiteral, kLiteral,
@ -244,6 +245,7 @@ namespace lsp::language::ast
// ===== 前向声明 ===== // ===== 前向声明 =====
class ASTNode; class ASTNode;
class Program;
class Expression; class Expression;
class Statement; class Statement;
class Declaration; class Declaration;
@ -310,6 +312,7 @@ namespace lsp::language::ast
public: public:
virtual ~ASTVisitor() = default; virtual ~ASTVisitor() = default;
virtual void VisitProgram(Program& node) = 0;
virtual void VisitUnitDefinition(UnitDefinition& node) = 0; virtual void VisitUnitDefinition(UnitDefinition& node) = 0;
virtual void VisitMethodDeclaration(MethodDeclaration& node) = 0; virtual void VisitMethodDeclaration(MethodDeclaration& node) = 0;
virtual void VisitPropertyDeclaration(PropertyDeclaration& node) = 0; virtual void VisitPropertyDeclaration(PropertyDeclaration& node) = 0;
@ -864,14 +867,14 @@ namespace lsp::language::ast
ExpressionPtr value; ExpressionPtr value;
}; };
class UsesStatement: public Statement class UsesStatement : public Statement
{ {
public: public:
UsesStatement() { kind = NodeKind::kUsesStatement; } UsesStatement() { kind = NodeKind::kUsesStatement; }
void Accept(ASTVisitor& visitor) override { visitor.VisitUsesStatement(*this); } void Accept(ASTVisitor& visitor) override { visitor.VisitUsesStatement(*this); }
public: public:
std::vector<std::string> modules; std::vector<std::string> units;
}; };
struct Parameter struct Parameter
@ -1017,6 +1020,16 @@ namespace lsp::language::ast
std::string operator_symbol; std::string operator_symbol;
}; };
class Program : public ASTNode
{
public:
Program() { kind = NodeKind::kProgram; }
void Accept(ASTVisitor& visitor) override { visitor.VisitProgram(*this); }
public:
std::vector<StatementPtr> statements;
};
template<typename T, typename... Args> template<typename T, typename... Args>
std::unique_ptr<T> MakeNode(Args&&... args) std::unique_ptr<T> MakeNode(Args&&... args)
{ {

View File

@ -7884,7 +7884,7 @@
"members": [ "members": [
{ {
"type": "FIELD", "type": "FIELD",
"name": "module", "name": "unit",
"content": { "content": {
"type": "SYMBOL", "type": "SYMBOL",
"name": "identifier" "name": "identifier"
@ -7901,7 +7901,7 @@
}, },
{ {
"type": "FIELD", "type": "FIELD",
"name": "module", "name": "unit",
"content": { "content": {
"type": "SYMBOL", "type": "SYMBOL",
"name": "identifier" "name": "identifier"

View File

@ -5659,7 +5659,7 @@
"type": "uses_statement", "type": "uses_statement",
"named": true, "named": true,
"fields": { "fields": {
"module": { "unit": {
"multiple": true, "multiple": true,
"required": true, "required": true,
"types": [ "types": [

View File

@ -3073,32 +3073,32 @@ enum ts_field_identifiers {
field_left_fields = 44, field_left_fields = 44,
field_method_name = 45, field_method_name = 45,
field_modifier = 46, field_modifier = 46,
field_module = 47, field_name = 47,
field_name = 48, field_object = 48,
field_object = 49, field_operator = 49,
field_operator = 50, field_order_by = 50,
field_order_by = 51, field_parameter = 51,
field_parameter = 52, field_parameters = 52,
field_parameters = 53, field_parent = 53,
field_parent = 54, field_part = 54,
field_part = 55, field_read = 55,
field_read = 56, field_ref = 56,
field_ref = 57, field_ref_modifier = 57,
field_ref_modifier = 58, field_reference_modifier = 58,
field_reference_modifier = 59, field_return_type = 59,
field_return_type = 60, field_right = 60,
field_right = 61, field_right_fields = 61,
field_right_fields = 62, field_source = 62,
field_source = 63, field_start = 63,
field_start = 64, field_subscript = 64,
field_subscript = 65, field_table = 65,
field_table = 66, field_table_index = 66,
field_table_index = 67, field_tag_name = 67,
field_tag_name = 68, field_target = 68,
field_target = 69, field_total = 69,
field_total = 70, field_try_body = 70,
field_try_body = 71, field_type_name = 71,
field_type_name = 72, field_unit = 72,
field_value = 73, field_value = 73,
field_variable = 74, field_variable = 74,
field_where = 75, field_where = 75,
@ -3153,7 +3153,6 @@ static const char * const ts_field_names[] = {
[field_left_fields] = "left_fields", [field_left_fields] = "left_fields",
[field_method_name] = "method_name", [field_method_name] = "method_name",
[field_modifier] = "modifier", [field_modifier] = "modifier",
[field_module] = "module",
[field_name] = "name", [field_name] = "name",
[field_object] = "object", [field_object] = "object",
[field_operator] = "operator", [field_operator] = "operator",
@ -3179,6 +3178,7 @@ static const char * const ts_field_names[] = {
[field_total] = "total", [field_total] = "total",
[field_try_body] = "try_body", [field_try_body] = "try_body",
[field_type_name] = "type_name", [field_type_name] = "type_name",
[field_unit] = "unit",
[field_value] = "value", [field_value] = "value",
[field_variable] = "variable", [field_variable] = "variable",
[field_where] = "where", [field_where] = "where",
@ -3603,7 +3603,7 @@ static const TSFieldMapEntry ts_field_map_entries[] = {
[62] = [62] =
{field_table, 2}, {field_table, 2},
[63] = [63] =
{field_module, 1}, {field_unit, 1},
[64] = [64] =
{field_left, 0}, {field_left, 0},
{field_operator, 1}, {field_operator, 1},
@ -3727,11 +3727,11 @@ static const TSFieldMapEntry ts_field_map_entries[] = {
[143] = [143] =
{field_try_body, 1}, {field_try_body, 1},
[144] = [144] =
{field_module, 1}, {field_unit, 1},
{field_module, 2, .inherited = true}, {field_unit, 2, .inherited = true},
[146] = [146] =
{field_module, 0, .inherited = true}, {field_unit, 0, .inherited = true},
{field_module, 1, .inherited = true}, {field_unit, 1, .inherited = true},
[148] = [148] =
{field_alternative, 3}, {field_alternative, 3},
{field_condition, 0}, {field_condition, 0},