为了更为结构化的生成中间代码,本文将SysY文法与Clang类一一对应,以重构出节点类,重新构建AST(之前的树顶多算是Parse tree,而非AST)
一、声明
1、变量声明
先从最简单的情况开始:
const int a = 1; int b = 2;
AST对应结构:
VarDecl 0x26b281623d8 <.\main.c:1:1, col:15> col:11 a 'const int' cinit | `-IntegerLiteral 0x26b283b7958 <col:15> 'int' 1 `-VarDecl 0x26b283b7998 <line:2:1, col:9> col:5 b 'int' cinit `-IntegerLiteral 0x26b283b7a00 <col:9> 'int' 2
可见简单的变量声明,表观来看是由同一个 VarDecl 表征的。
再看一下更为复杂的定义:
int b = 2 + 3 * 2;
VarDecl 0x18bde6123d8 <.\main.c:1:1, col:17> col:5 b 'int' cinit `-BinaryOperator 0x18bde8a9a10 <col:9, col:17> 'int' '+' |-IntegerLiteral 0x18bde8a9978 <col:9> 'int' 2 `-BinaryOperator 0x18bde8a99f0 <col:13, col:17> 'int' '*' |-IntegerLiteral 0x18bde8a99a0 <col:13> 'int' 3 `-IntegerLiteral 0x18bde8a99c8 <col:17> 'int' 2
可见定义中的表达式计算,是由 BinaryOperator 类主导的。
最后看一下更为复杂的变量引用:
const int a = 2; int b = 2 + 3 * a;
`-VarDecl 0x1baf8b38178 <line:2:1, col:17> col:5 b 'int' cinit `-BinaryOperator 0x1baf8b38288 <col:9, col:17> 'int' '+' |-IntegerLiteral 0x1baf8b381e0 <col:9> 'int' 2 `-BinaryOperator 0x1baf8b38268 <col:13, col:17> 'int' '*' |-IntegerLiteral 0x1baf8b38208 <col:13> 'int' 3 `-ImplicitCastExpr 0x1baf8b38250 <col:17> 'int' <LValueToRValue> `-DeclRefExpr 0x1baf8b38230 <col:17> 'const int' lvalue Var 0x1baf8876be8 'a' 'const int'
看得出,这种变量引用,是DeclRefExpr表征的,外层ImplicitCastExpr是CastExpr的子类,而后者是用于类型转换,易知我们的实验不涉及这一点。
2、函数声明
main函数
int main() { return 0; }
FunctionDecl 0x276074f9160 <.\main.c:1:1, line:3:1> line:1:5 main 'int ()' `-CompoundStmt 0x276074f9280 <col:12, line:3:1> `-ReturnStmt 0x276074f9270 <line:2:2, col:9> `-IntegerLiteral 0x276074f9248 <col:9> 'int' 0
自定义函数
int f1(int a) { } void