简体   繁体   English

如何在clang抽象语法树的右侧获得整个表达式?

[英]How to get the entire expression on the right hand side of clang abstract syntax tree?

Let us take a toy example, say I have the following code in test.cpp file: 让我们以一个玩具示例为例,说我在test.cpp文件中有以下代码:

int main()
{
    int gt = 3; 
    int g = 10 / gt;
}

I want to find the variable name of the denominator in the division operation, then using clang I get the abstract syntax tree (AST) of the above code using the command clang -Xclang -ast-dump -fsyntax-only test.cpp . 我想在除法运算中找到分母的变量名,然后使用clang命令clang -Xclang -ast-dump -fsyntax-only test.cpp获得上述代码的抽象语法树(AST)。 I get the following output 我得到以下输出

TranslationUnitDecl 0x34f8100 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x34f8638 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x34f8350 '__int128'
|-TypedefDecl 0x34f8698 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x34f8370 'unsigned __int128'
|-TypedefDecl 0x34f8728 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x34f86f0 'char *'
|   `-BuiltinType 0x34f8190 'char'
|-TypedefDecl 0x34f8a48 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'struct __va_list_tag [1]'
| `-ConstantArrayType 0x34f89f0 'struct __va_list_tag [1]' 1 
|   `-RecordType 0x34f8810 'struct __va_list_tag'
|     `-CXXRecord 0x34f8778 '__va_list_tag'
`-FunctionDecl 0x34f8af0 <test.cpp:1:1, line:5:1> line:1:5 main 'int (void)'
  `-CompoundStmt 0x34f8dc0 <line:2:1, line:5:1>
    |-DeclStmt 0x34f8c98 <line:3:2, col:12>
    | `-VarDecl 0x34f8c18 <col:2, col:11> col:6 used gt 'int' cinit
    |   `-IntegerLiteral 0x34f8c78 <col:11> 'int' 3
    `-DeclStmt 0x34f8da8 <line:4:2, col:17>
      `-VarDecl 0x34f8cc0 <col:2, col:15> col:6 g 'int' cinit
        `-BinaryOperator 0x34f8d80 <col:10, col:15> 'int' '/'
          |-IntegerLiteral 0x34f8d20 <col:10> 'int' 10
          `-ImplicitCastExpr 0x34f8d68 <col:15> 'int' <LValueToRValue>
            `-DeclRefExpr 0x34f8d40 <col:15> 'int' lvalue Var 0x34f8c18 'gt' 'int'

From the knowledge of above AST and using clang-query, I get the variable name of the denominator using the following command 根据以上AST的知识并使用clang-query,我可以使用以下命令获取分母的变量名称

clang-query> match declRefExpr(isExpansionInMainFile(), allOf(hasAncestor(binaryOperator(hasOperatorName("/"))), hasAncestor(declStmt())  ))

I get my output as 我得到的输出为

Match #1:

/home/clang-llvm/cpp/code/test.cpp:4:15: note: "root" binds here
        int g = 10 / gt;
                     ^~
1 match.

Now that we are on the same page, I have two questions. 现在我们在同一页上,我有两个问题。

  1. Here in the above toy example, instead of 10 if I have another variable then my query matches both the variables (numerator and denominator). 在上面的玩具示例中,如果我有另一个变量,那么我的查询将匹配两个变量(分子和分母),而不是10。 How can I restrict my clang-query to match only the variable that is the denominator of the division operation? 如何限制我的clang查询仅匹配作为除法运算分母的变量? In other words, how to find the variable that is present in the right hand side of the binary operator "/" ? 换句话说,如何找到存在于二进制运算符“ /”右侧的变量? An example is int g = gw / gt; 一个例子是int g = gw / gt;

  2. Instead of a variable gt, if I have an expression in the denominator then how can I get the whole expression using clang? 如果我在分母中有一个表达式,而不是变量gt,那么如何使用clang获得整个表达式? In other words, how to get expression that is on the right hand side of the binary operator "/" in the abstract syntax tree? 换句话说,如何获取抽象语法树中二进制运算符“ /”右侧的表达式? A simple example could be int g = gw / (gt - gw); 一个简单的例子可以是int g = gw / (gt - gw); and a complex example could be int g = gw / gt - gw / gr * gg / sqrt( gt - gw ^ 2) + gq; 一个复杂的例子可能是int g = gw / gt - gw / gr * gg / sqrt( gt - gw ^ 2) + gq;

I appreciate any help in this regard. 我感谢在这方面的任何帮助。

Clang has a traversal matcher "hasRHS()", which does exactly what you want. Clang有一个遍历匹配器“ hasRHS()”,它可以完全满足您的要求。

int main()
{
    int gt = 3;
    int g = 10 / gt;

    int gw, gg, gr, gq;
    int g1 = gw / gt;
    int g2 = gw / (gt-gw);
    int g3 = gw / gt - gw / gr * gg / ( gt - gw ^ 2) + gq;
    return 0;
}

Output: 输出:

clang-query> match varDecl(hasDescendant(binaryOperator(hasOperatorName("/"), hasRHS(expr().bind("myExpr")))))

Match #1:
/home/test.cpp:4:18: note: "myExpr" binds here
    int g = 10 / gt;
                 ^~
/home/test.cpp:4:5: note: "root" binds here
    int g = 10 / gt;
    ^~~~~~~~~~~~~~~

Match #2:
/home/test.cpp:7:19: note: "myExpr" binds here
    int g1 = gw / gt;
                  ^~
/home/test.cpp:7:5: note: "root" binds here
    int g1 = gw / gt;
    ^~~~~~~~~~~~~~~~

Match #3:
/home/test.cpp:8:19: note: "myExpr" binds here
    int g2 = gw / (gt-gw);
                  ^~~~~~~
/home/test.cpp:8:5: note: "root" binds here
    int g2 = gw / (gt-gw);
    ^~~~~~~~~~~~~~~~~~~~~

Match #4:
/home/test.cpp:9:19: note: "myExpr" binds here
    int g3 = gw / gt - gw / gr * gg / ( gt - gw ^ 2) + gq;
                  ^~
/home/test.cpp:9:5: note: "root" binds here
    int g3 = gw / gt - gw / gr * gg / ( gt - gw ^ 2) + gq;
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 matches.

"myExpr" is bind to what you want. “ myExpr”绑定到您想要的内容。 Ref: http://clang.llvm.org/docs/LibASTMatchersReference.html 参考: http : //clang.llvm.org/docs/LibASTMatchersReference.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何访问序列化的 clang 抽象语法树 (AST) - How to visit a serialized clang abstract syntax tree (AST) 与赋值表达式的C ++比较是右侧表达式 - C++ comparison with an assignment expression be the right hand side expression Clang:AST(抽象语法树)是什么样的? - Clang : What does AST (abstract syntax tree) look like? 如何在C ++中从右侧使用substr获取字符串 - how to use substr get string from right hand side in c++ 如何以图形方式可视化抽象语法树? - How to visualize an Abstract Syntax Tree graphically? 这种情况下的抽象语法树? - Abstract Syntax Tree for this case? 如何从屏幕右侧而不是 C 中通常的左侧按 output 进行打印? - How to print by output from the right hand side of the screen instead of the usual left hand side in C? 如何在左右两侧创建运算符*(double)以进行相乘? - How to create operator*(double) for multiplying on both the left and right hand side? 如何在 rtl 对齐中打开右侧的子菜单? - How to open sub-menu on right hand side in rtl alignments? C#指针:错误CS0254:固定语句赋值的右侧可能不是强制转换表达式 - C# Pointer: error CS0254: The right hand side of a fixed statement assignment may not be a cast expression
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM