查看C语言表达式的抽象语法树 #
对表达式的求值过程,实际上就是根据运算符的优先级和结合性,来对表达式和它所包含的子表达式进行递归求值的过程。从编译的角度来看,这个过程中所涉及到的操作数的实际求值顺序会在语法分析阶段被确定,并体现在源码对应的抽象语法树(AST,Abstract Syntax Tree)上。为了方便进一步观察,我将这个表达式整合到了下面的 C 代码里,并保存在文件 main.c 中:
int foo(void) {
return (1 + 2) * 3 + 4 / 5;
}
然后,借助 Clang 编译器提供的 “-ast-dump” 选项,我们可以编译并打印出这段 C 代码对应的 AST 结构。完整的编译命令如下:
clang -Xclang -ast-dump -fsyntax-only main.c
上面的命令执行完毕后,部分输出结果如下图所示:
`-FunctionDecl 0x616600 <main.c:1:1, line:3:1> line:1:5 foo 'int (void)'
`-CompoundStmt 0x616838 <col:15, line:3:1>
`-ReturnStmt 0x616828 <line:2:7, col:32>
`-BinaryOperator 0x616808 <col:14, col:32> 'int' '+'
|-BinaryOperator 0x616788 <col:14, col:24> 'int' '*'
| |-ParenExpr 0x616748 <col:14, col:20> 'int'
| | `-BinaryOperator 0x616728 <col:15, col:19> 'int' '+'
| | |-IntegerLiteral 0x6166e8 <col:15> 'int' 1
| | `-IntegerLiteral 0x616708 <col:19> 'int' 2
| `-IntegerLiteral 0x616768 <col:24> 'int' 3
`-BinaryOperator 0x6167e8 <col:28, col:32> 'int' '/'
|-IntegerLiteral 0x6167a8 <col:28> 'int' 4
`-IntegerLiteral 0x6167c8 <col:32> 'int' 5
AST 作为用于表示源代码语法结构的一种树形数据结构,语法分析器会将表达式中操作数的整体求值顺序映射到树的结构上。因此,当我们以后序遍历(LRD)的方式遍历这棵树时,便可以直接得到正确的表达式求值顺序。