improve ast
This commit is contained in:
parent
dbccd5b605
commit
7d9b966bc7
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue