解析 Clang AST - 缩进级别和起始符号
Parsing Clang AST - indentation level and starting symbol
我必须手动解析 Clang AST,但是我在理解描述节点之间链接的缩进规则时遇到了一些麻烦。让我们举一个简单的例子。对于以下代码,
int f(int x) {
int result = (x / 42);
return result;
}
生成的 AST 是
... cutting out internal declarations of clang ...
`-FunctionDecl 0x5aeab50 <test.cc:1:1, line:4:1> f 'int (int)'
|-ParmVarDecl 0x5aeaa90 <line:1:7, col:11> x 'int'
`-CompoundStmt 0x5aead88 <col:14, line:4:1>
|-DeclStmt 0x5aead10 <line:2:3, col:24>
| `-VarDecl 0x5aeac10 <col:3, col:23> result 'int'
| `-ParenExpr 0x5aeacf0 <col:16, col:23> 'int'
| `-BinaryOperator 0x5aeacc8 <col:17, col:21> 'int' '/'
| |-ImplicitCastExpr 0x5aeacb0 <col:17> 'int' <LValueToRValue>
| | `-DeclRefExpr 0x5aeac68 <col:17> 'int' lvalue ParmVar 0x5aeaa90 'x' 'int'
| `-IntegerLiteral 0x5aeac90 <col:21> 'int' 42
`-ReturnStmt 0x5aead68 <line:3:3, col:10>
`-ImplicitCastExpr 0x5aead50 <col:10> 'int' <LValueToRValue>
`-DeclRefExpr 0x5aead28 <col:10> 'int' lvalue Var 0x5aeac10 'result' 'int'
注意: 为了避免引号的格式问题,我将其替换为 \
我真的不明白什么时候我们可以判断两个节点具有相同的parent。我显然明白这取决于识别级别,但是例如第三行以 \-
开头所以我猜 \
意味着 CompoundStmt
是 child ParmVarDecl
。然而,缩进级别是相同的。
第 4 行,DeclStmt
比上一行缩进了很多,但是没有 \
符号所以它被认为是 CompoundStmt
的子节点或者它的 child ?
最后,在DeclStmt
中我们有越来越多的以[=13=开头的缩进行],这和第3行(以[=13=开头)有什么区别=] 也是,但与上一行具有相同的缩进级别) ?
谁能给我解释一下这个起始符号和缩进级别的语义?
用 unicode U+2514 替换他们的角符号(他们限制自己使用 ASCII)方块图亮起并向右 └
,你会看得更清楚:
... cutting out internal declarations of clang ...
└─FunctionDecl 0x5aeab50 <test.cc:1:1, line:4:1> f 'int (int)'
├─ParmVarDecl 0x5aeaa90 <line:1:7, col:11> x 'int'
└─CompoundStmt 0x5aead88 <col:14, line:4:1>
├─DeclStmt 0x5aead10 <line:2:3, col:24>
│ └─VarDecl 0x5aeac10 <col:3, col:23> result 'int'
│ └─ParenExpr 0x5aeacf0 <col:16, col:23> 'int'
│ └─BinaryOperator 0x5aeacc8 <col:17, col:21> 'int' '/'
│ ├─ImplicitCastExpr 0x5aeacb0 <col:17> 'int' <LValueToRValue>
│ │ └─DeclRefExpr 0x5aeac68 <col:17> 'int' lvalue ParmVar 0x5aeaa90 'x' 'int'
│ └─IntegerLiteral 0x5aeac90 <col:21> 'int' 42
└─ReturnStmt 0x5aead68 <line:3:3, col:10>
└─ImplicitCastExpr 0x5aead50 <col:10> 'int' <LValueToRValue>
└─DeclRefExpr 0x5aead28 <col:10> 'int' lvalue Var 0x5aeac10 'result' 'int'
使用了更多的方框字符来美化线条...
我必须手动解析 Clang AST,但是我在理解描述节点之间链接的缩进规则时遇到了一些麻烦。让我们举一个简单的例子。对于以下代码,
int f(int x) {
int result = (x / 42);
return result;
}
生成的 AST 是
... cutting out internal declarations of clang ...
`-FunctionDecl 0x5aeab50 <test.cc:1:1, line:4:1> f 'int (int)'
|-ParmVarDecl 0x5aeaa90 <line:1:7, col:11> x 'int'
`-CompoundStmt 0x5aead88 <col:14, line:4:1>
|-DeclStmt 0x5aead10 <line:2:3, col:24>
| `-VarDecl 0x5aeac10 <col:3, col:23> result 'int'
| `-ParenExpr 0x5aeacf0 <col:16, col:23> 'int'
| `-BinaryOperator 0x5aeacc8 <col:17, col:21> 'int' '/'
| |-ImplicitCastExpr 0x5aeacb0 <col:17> 'int' <LValueToRValue>
| | `-DeclRefExpr 0x5aeac68 <col:17> 'int' lvalue ParmVar 0x5aeaa90 'x' 'int'
| `-IntegerLiteral 0x5aeac90 <col:21> 'int' 42
`-ReturnStmt 0x5aead68 <line:3:3, col:10>
`-ImplicitCastExpr 0x5aead50 <col:10> 'int' <LValueToRValue>
`-DeclRefExpr 0x5aead28 <col:10> 'int' lvalue Var 0x5aeac10 'result' 'int'
注意: 为了避免引号的格式问题,我将其替换为 \
我真的不明白什么时候我们可以判断两个节点具有相同的parent。我显然明白这取决于识别级别,但是例如第三行以
\-
开头所以我猜\
意味着CompoundStmt
是 childParmVarDecl
。然而,缩进级别是相同的。第 4 行,
DeclStmt
比上一行缩进了很多,但是没有\
符号所以它被认为是CompoundStmt
的子节点或者它的 child ?最后,在
DeclStmt
中我们有越来越多的以[=13=开头的缩进行],这和第3行(以[=13=开头)有什么区别=] 也是,但与上一行具有相同的缩进级别) ?
谁能给我解释一下这个起始符号和缩进级别的语义?
用 unicode U+2514 替换他们的角符号(他们限制自己使用 ASCII)方块图亮起并向右 └
,你会看得更清楚:
... cutting out internal declarations of clang ...
└─FunctionDecl 0x5aeab50 <test.cc:1:1, line:4:1> f 'int (int)'
├─ParmVarDecl 0x5aeaa90 <line:1:7, col:11> x 'int'
└─CompoundStmt 0x5aead88 <col:14, line:4:1>
├─DeclStmt 0x5aead10 <line:2:3, col:24>
│ └─VarDecl 0x5aeac10 <col:3, col:23> result 'int'
│ └─ParenExpr 0x5aeacf0 <col:16, col:23> 'int'
│ └─BinaryOperator 0x5aeacc8 <col:17, col:21> 'int' '/'
│ ├─ImplicitCastExpr 0x5aeacb0 <col:17> 'int' <LValueToRValue>
│ │ └─DeclRefExpr 0x5aeac68 <col:17> 'int' lvalue ParmVar 0x5aeaa90 'x' 'int'
│ └─IntegerLiteral 0x5aeac90 <col:21> 'int' 42
└─ReturnStmt 0x5aead68 <line:3:3, col:10>
└─ImplicitCastExpr 0x5aead50 <col:10> 'int' <LValueToRValue>
└─DeclRefExpr 0x5aead28 <col:10> 'int' lvalue Var 0x5aeac10 'result' 'int'
使用了更多的方框字符来美化线条...