gpt4 book ai didi

clang - 特定节点上的 AST 匹配器

转载 作者:行者123 更新时间:2023-12-02 19:39:35 24 4
gpt4 key购买 nike

我编写了一个 AST 匹配器来查找特定类型语句。在匹配的节点中,我计算了该节点的邻居兄弟节点。现在我需要在邻居节点上运行匹配器来验证它们是否满足我的条件。clang AST 匹配器将整个树节点一一匹配。我想针对特定节点运行匹配器,如果该节点符合我所需的条件,则返回 true。这可能吗?

最佳答案

我建议实现您自己的匹配器,它将封装查找邻居节点并将它们与其他匹配器进行匹配的逻辑。

我整理了以下匹配器作为如何完成此操作的示例:

using clang::ast_matchers::internal::Matcher;
constexpr auto AVERAGE_NUMBER_OF_NESTED_MATCHERS = 3;
using Matchers =
llvm::SmallVector<Matcher<clang::Stmt>, AVERAGE_NUMBER_OF_NESTED_MATCHERS>;


clang::Stmt *getNeighbor(const clang::Stmt &Node, clang::ASTContext &Context) {
// It is my naive implementation of this method, you can easily put your own
auto Parents = Context.getParents(Node);
if (Parents.size() != 1) {
return nullptr;
}

// As we deal with statements, let's assume that neighbor - is the next
// statement in the enclosing compound statement.
if (auto *Parent = Parents[0].get<clang::CompoundStmt>()) {
auto Neighbor = std::adjacent_find(
Parent->body_begin(), Parent->body_end(),
[&Node](const auto *Top, const auto *Bottom) { return Top == &Node; });

if (Neighbor != Parent->body_end()) {
return *std::next(Neighbor);
}
}

return nullptr;
}

AST_MATCHER_P(clang::Stmt, neighbors, Matchers, NestedMatchers) {
// Node is the current tested node
const clang::Stmt *CurrentNode = &Node;

// Our goal is to iterate over the given matchers and match the current node
// with the first matcher.
//
// Further on, we plan on checking whether the next
// matcher matches the neighbor/sibling of the previous node.
for (auto NestedMatcher : NestedMatchers) {
// This is how one can call a matcher to test one node.
//
// NOTE: it uses Finder and Builder, so it's better to do it from
// inside of a matcher and get those for free
if (CurrentNode == nullptr or
not NestedMatcher.matches(*CurrentNode, Finder, Builder)) {
return false;
}

// Here you can put your own implementation of finding neighbor/sibling
CurrentNode = getNeighbor(*CurrentNode, Finder->getASTContext());
}

return true;
}

我希望代码片段中的评论涵盖了这个匹配器背后的主要思想。

演示

匹配器:

neighbors({declStmt().bind("first"), forStmt().bind("second"),
returnStmt().bind("third")})

代码片段:

int foo() {
int x = 42;
int y = 10;
for (; x > y; --x) {
}
return x;
}

输出:

first:
DeclStmt 0x4c683e0
`-VarDecl 0x4c68360 used y 'int' cinit
`-IntegerLiteral 0x4c683c0 'int' 10

second:
ForStmt 0x4c684d0
|-<<<NULL>>>
|-<<<NULL>>>
|-BinaryOperator 0x4c68468 '_Bool' '>'
| |-ImplicitCastExpr 0x4c68438 'int' <LValueToRValue>
| | `-DeclRefExpr 0x4c683f8 'int' lvalue Var 0x4c682b0 'x' 'int'
| `-ImplicitCastExpr 0x4c68450 'int' <LValueToRValue>
| `-DeclRefExpr 0x4c68418 'int' lvalue Var 0x4c68360 'y' 'int'
|-UnaryOperator 0x4c684a8 'int' lvalue prefix '--'
| `-DeclRefExpr 0x4c68488 'int' lvalue Var 0x4c682b0 'x' 'int'
`-CompoundStmt 0x4c684c0

third:
ReturnStmt 0x4c68540
`-ImplicitCastExpr 0x4c68528 'int' <LValueToRValue>
`-DeclRefExpr 0x4c68508 'int' lvalue Var 0x4c682b0 'x' 'int'

希望这能回答您的问题!

关于clang - 特定节点上的 AST 匹配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60439281/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com