improve ast

This commit is contained in:
csh 2025-10-26 22:51:52 +08:00
parent dbccd5b605
commit 7d9b966bc7
7 changed files with 2124 additions and 2224 deletions

View File

@ -1,4 +1,3 @@
#include <iostream>
#include "./detail.hpp"
#include "./tree_sitter_utils.hpp"
#include "./deserializer.hpp"
@ -19,8 +18,7 @@ namespace lsp::language::ast
detail::ParseContext ctx(source, result.errors);
auto program = std::make_unique<Program>();
program->location = ts::NodeLocation(root);
program->node_type_name = "program";
program->span = ts::NodeLocation(root);
uint32_t count = ts_node_child_count(root);
for (uint32_t i = 0; i < count; i++)
@ -53,8 +51,7 @@ namespace lsp::language::ast
detail::ParseContext ctx(source, result.result.errors);
auto program = std::make_unique<Program>();
program->location = ts::NodeLocation(root);
program->node_type_name = "program";
program->span = ts::NodeLocation(root);
uint32_t count = ts_node_child_count(root);
for (uint32_t i = 0; i < count; i++)
@ -75,6 +72,7 @@ namespace lsp::language::ast
program->statements.push_back(std::move(stmt));
}
result.result.root = std::move(program);
auto syntax_errors = detail::CollectSyntaxErrors(root, source);
result.result.errors.insert(result.result.errors.end(),
std::make_move_iterator(syntax_errors.begin()),

File diff suppressed because it is too large Load Diff

View File

@ -91,6 +91,8 @@ namespace lsp::language::ast
kUnpackPattern,
kCaseBranch,
kClassMember,
kMatrixIterationStatement,
};
// ===== 枚举类型 =====
@ -300,6 +302,7 @@ namespace lsp::language::ast
class ClassDefinition;
class UnitDefinition;
class TSSQLExpression;
class MatrixIterationStatement;
using ASTNodePtr = std::unique_ptr<ASTNode>;
using ExpressionPtr = std::unique_ptr<Expression>;
@ -362,6 +365,13 @@ namespace lsp::language::ast
virtual void VisitFieldDeclaration(FieldDeclaration& node) = 0;
virtual void VisitTSSQLExpression(TSSQLExpression& node) = 0;
virtual void VisitUnpackPattern(UnpackPattern& node) = 0;
virtual void VisitMatrixIterationStatement(MatrixIterationStatement& node) = 0;
};
struct TypeAnnotation
{
std::string name;
Location location;
};
// ===== 基类 ASTNode =====
@ -373,8 +383,7 @@ namespace lsp::language::ast
public:
NodeKind kind;
Location location;
std::string node_type_name;
Location span;
};
// ===== Expression 基类 =====
@ -395,6 +404,7 @@ namespace lsp::language::ast
public:
std::string name;
Location location;
};
class Literal : public Expression
@ -405,7 +415,8 @@ namespace lsp::language::ast
public:
LiteralKind literal_kind;
std::string value;
std::string name;
Location location;
};
class BinaryExpression : public Expression
@ -466,8 +477,8 @@ namespace lsp::language::ast
struct Argument
{
std::optional<std::string> name;
std::optional<Location> location;
ExpressionPtr value;
bool is_spread = false;
};
CallExpression() { kind = NodeKind::kCallExpression; }
@ -485,8 +496,9 @@ namespace lsp::language::ast
void Accept(ASTVisitor& visitor) override { visitor.VisitAttributeExpression(*this); }
public:
std::string name;
Location location;
ExpressionPtr object;
std::string attribute;
};
class SubscriptExpression : public Expression
@ -594,7 +606,8 @@ namespace lsp::language::ast
public:
std::string name;
std::optional<std::string> type_name;
Location location;
std::optional<TypeAnnotation> type;
ExpressionPtr initial_value;
};
@ -605,10 +618,11 @@ namespace lsp::language::ast
void Accept(ASTVisitor& visitor) override { visitor.VisitStaticDeclaration(*this); }
public:
std::string name;
std::optional<std::string> type_name;
ExpressionPtr initial_value;
ReferenceModifier reference_modifier = ReferenceModifier::kNone;
std::string name;
Location location;
std::optional<TypeAnnotation> type;
ExpressionPtr initial_value;
};
class GlobalDeclaration : public ASTNode
@ -619,7 +633,8 @@ namespace lsp::language::ast
public:
std::string name;
std::optional<std::string> type_name;
Location location;
std::optional<TypeAnnotation> type;
ExpressionPtr initial_value;
};
@ -631,7 +646,7 @@ namespace lsp::language::ast
public:
std::string name;
std::optional<std::string> type_name;
std::optional<TypeAnnotation> type;
ExpressionPtr initial_value;
ReferenceModifier reference_modifier = ReferenceModifier::kNone;
};
@ -880,17 +895,17 @@ namespace lsp::language::ast
struct Parameter
{
std::string name;
std::optional<std::string> type_name;
Location location;
std::optional<TypeAnnotation> type;
ExpressionPtr default_value;
bool is_var = false;
bool is_out = false;
Location location;
};
struct Signature
{
std::vector<Parameter> parameters;
std::optional<std::string> return_type;
std::optional<TypeAnnotation> return_type;
};
class FunctionDefinition : public Statement
@ -901,6 +916,7 @@ namespace lsp::language::ast
public:
std::string name;
Location location;
Signature signature;
StatementPtr body;
bool is_overload;
@ -914,6 +930,7 @@ namespace lsp::language::ast
public:
std::string name;
Location location;
Signature signature;
bool is_overload;
};
@ -937,13 +954,13 @@ namespace lsp::language::ast
public:
std::string name;
Location location;
Signature signature;
StatementPtr body;
MethodModifier modifier = MethodModifier::kNone;
MethodType method_type = MethodType::kNormal;
bool is_class_method = false;
bool is_operator_overload = false;
std::string operator_symbol;
};
class PropertyDeclaration : public Statement
@ -954,6 +971,7 @@ namespace lsp::language::ast
public:
std::string name;
Location location;
std::optional<std::string> type_name;
std::optional<std::string> index_value;
std::optional<std::string> read_accessor;
@ -982,9 +1000,19 @@ namespace lsp::language::ast
ClassDefinition() { kind = NodeKind::kClassDefinition; }
void Accept(ASTVisitor& visitor) override { visitor.VisitClassDefinition(*this); }
struct ParentClass
{
std::optional<std::string> qualifier;
std::optional<Location> qualifier_location;
std::string name;
Location location;
};
public:
std::string name;
std::vector<std::string> parent_classes;
Location location;
std::vector<ParentClass> parent_classes;
std::vector<std::unique_ptr<ClassMember>> members;
};
@ -996,6 +1024,7 @@ namespace lsp::language::ast
public:
std::string name;
Location location;
std::vector<StatementPtr> interface_statements;
std::vector<StatementPtr> implementation_statements;
std::vector<StatementPtr> initialization_statements;
@ -1009,15 +1038,30 @@ namespace lsp::language::ast
void Accept(ASTVisitor& visitor) override { visitor.VisitExternalMethodDefinition(*this); }
public:
std::string owner_class;
struct
{
std::string name;
Location location;
} owner_class;
std::string name;
Location location;
Signature signature;
StatementPtr body;
MethodModifier modifier = MethodModifier::kNone;
MethodType method_type = MethodType::kNormal;
bool is_operator_overload = false;
bool is_class_method = false;
std::string operator_symbol;
};
class MatrixIterationStatement : public Statement
{
public:
MatrixIterationStatement() { kind = NodeKind::kMatrixIterationStatement; }
void Accept(ASTVisitor& visitor) override { visitor.VisitMatrixIterationStatement(*this); }
public:
ExpressionPtr target;
StatementPtr body;
};
class Program : public ASTNode

File diff suppressed because it is too large Load Diff

View File

@ -126,8 +126,8 @@ namespace lsp::language::ast
void VisitRepeatStatement(RepeatStatement& node) override;
void VisitCaseStatement(CaseStatement& node) override;
void VisitTryStatement(TryStatement& node) override;
void VisitBreakStatement(BreakStatement& node) override;
void VisitContinueStatement(ContinueStatement& node) override;
void VisitBreakStatement(BreakStatement&) override;
void VisitContinueStatement(ContinueStatement&) override;
void VisitReturnStatement(ReturnStatement& node) override;
void VisitUsesStatement(UsesStatement& node) override;
void VisitFunctionDefinition(FunctionDefinition& node) override;
@ -138,6 +138,7 @@ namespace lsp::language::ast
void VisitFieldDeclaration(FieldDeclaration& node) override;
void VisitUnpackPattern(UnpackPattern& node) override;
void VisitTSSQLExpression(TSSQLExpression& node) override;
void VisitMatrixIterationStatement(MatrixIterationStatement& node) override;
private:
std::ostream& os_;
@ -163,6 +164,7 @@ namespace lsp::language::ast
void PrintNodeHeader(const std::string& type_name, const Location& loc);
void PrintLocation(const Location& loc);
void PrintSourceSnippet(const Location& loc);
void PrintKeyValue(const std::string& key, const std::string& value, const Location& location, const char* value_color);
void PrintKeyValue(const std::string& key, const std::string& value, const char* value_color = nullptr);
void PrintKeyValue(const std::string& key, int value);
void PrintKeyValue(const std::string& key, bool value);

View File

@ -0,0 +1,86 @@
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 测试的可执行文件路径
TEST_AST="./test_ast"
# 需要测试的目录列表(可以自行添加)
DIRECTORIES=(
"./tests"
"./examples"
"./samples"
# 在这里添加更多目录
# "./another_directory"
)
# 检查test_ast是否存在
if [ ! -f "$TEST_AST" ]; then
echo -e "${RED}错误: 找不到 test_ast 可执行文件${NC}"
echo "请确保 test_ast 在当前目录下,或修改脚本中的 TEST_AST 变量"
exit 1
fi
# 统计变量
total_files=0
tested_files=0
failed_files=0
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}开始测试 TSF 文件${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# 遍历每个目录
for dir in "${DIRECTORIES[@]}"; do
if [ ! -d "$dir" ]; then
echo -e "${YELLOW}警告: 目录不存在: $dir${NC}"
continue
fi
echo -e "${BLUE}扫描目录: $dir${NC}"
# 递归查找所有.tsf文件
while IFS= read -r -d '' file; do
((total_files++))
echo -e "${YELLOW}[测试]${NC} $file"
# 运行test_ast隐藏输出
if "$TEST_AST" "$file" > /dev/null 2>&1; then
((tested_files++))
echo -e "${GREEN} ✓ 通过${NC}"
else
((failed_files++))
echo -e "${RED} ✗ 失败${NC}"
echo -e "${RED}========================================${NC}"
echo -e "${RED}测试失败: $file${NC}"
echo -e "${RED}========================================${NC}"
exit 1
fi
done < <(find "$dir" -type f -name "*.tsf" -print0 | sort -z)
echo ""
done
# 打印总结
echo -e "${BLUE}========================================${NC}"
echo -e "${GREEN}所有测试完成!${NC}"
echo -e "${BLUE}========================================${NC}"
echo -e "总文件数: $total_files"
echo -e "已测试: $tested_files"
echo -e "失败: $failed_files"
if [ $failed_files -eq 0 ]; then
echo -e "${GREEN}✓ 全部通过${NC}"
exit 0
else
echo -e "${RED}✗ 存在失败${NC}"
exit 1
fi

View File

@ -1,20 +1,10 @@
var d, e: boolean;
global c, d;
static e, f;
const a: boolean = false;
function f1(a: string; b: boolean = true): integer;
begin
end;
var a, b: boolean := true;
static d := "abc";
global c := 123456;
// e := f1();
// function f1(a: string; b: boolean = true): integer;
// begin
// end;
// function f2(a, b, c);overload;
// begin
// end;
function f2(a, b, c);overload;
begin
end;
// var d := 1;
// c := false;