首页 > 解决方案 > Clang AST Matcher 和 AST Visitor 有什么区别?

问题描述

两种打开 Clang 盒子的强大方法。在决定使用其中一种时我应该考虑什么?

Clang 网站提供了一些关于如何使用查找 AST 节点的旧教程,以及一些关于如何使用查找某些stmt的新教程。在这种情况下,他们可以实现的目标有很多重叠之处。RecursiveASTVisitorDeclASTMatcherfor

对于上面提到的简单任务,我觉得ASTMatcher更方便,因为使用的谓词简短易读。但是,对于更复杂的任务,例如源到源的转换,需要对整个翻译单元进行分析。实现访问者功能似乎是一种更好的方法。因为我的谓词ASTMatcher往往会变得冗长且难以理解。也许有一种有效的方法来使用ASTMatcherlang 和复杂的谓词。我很感激对此的任何建议。既然ASTMatcher是后来介绍的,是不是打算替换旧AST Visitor方法呢?

标签: c++clangabstract-syntax-treematchervisitor-pattern

解决方案


好问题。有时,匹配器对于涉及可变数量的 AST 节点和您正在寻找的两个模式之间的复杂性的模式类型是不可行的。这是一个例子:

例如,匹配任何具有 name 的类Foo,并且它的所有方法中都有一个变量y。AST 看起来像:

|-CXXRecordDecl 0x563295d82010 <sandbox/class.cpp:1:1, line:6:1> line:1:7 class Foo definition
...
| |-CXXRecordDecl 0x563295d82128 <col:1, col:7> col:7 implicit class Foo
| |-FieldDecl 0x563295d821d0 <line:2:5, col:9> col:9 x 'int'
| `-CXXMethodDecl 0x563295d82298 <line:3:5, line:5:5> line:3:10 bar 'void ()'
|   `-CompoundStmt 0x563295d823e8 <col:16, line:5:5>
|     `-DeclStmt 0x563295d823d0 <line:4:9, col:14>
|       `-VarDecl 0x563295d82368 <col:9, col:13> col:13 y 'int'

对于单个函数。据我所知,没有简单的方法可以匹配所有 methoddecls 并匹配通配符数量的 stmts,直到您到达y定义中的变量。为此使用 AST 访问者模式符合您的最大利益。


推荐阅读