嗨,我是编译器开发的新手,我想知道AST是什么样子的。我有一小段代码,并且我使用Clang来生成AST。我从中得不到太多信息。从外观上看,语法树与源代码完全相同,除了添加到我测试的几乎所有样本中的一个结构。
来源:
class A {
public:
int *a, *b, *c;
int i;
void sum() {
a = new int[5];
b = new int[5];
c = new int[5];
for (i = 0; i < 5; i++) {
a[i] = i;
b[i] = i;
}
for (i = 0; i < 5; i++) {
c[i] = a[i] + b[i];
}
delete[] a; delete[] b; delete[] c;
}
};
class B : public A {
};
int main() {
B bclass;
bclass.sum();
return 0;
} 生成AST的命令:
clang++ -cc1 -ast-print ~/sum.cppAST输出:
struct __va_list_tag {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
};
typedef struct __va_list_tag __va_list_tag;
class A {
public:
int *a;
int *b;
int *c;
int i;
void sum() {
this->a = new int [5];
this->b = new int [5];
this->c = new int [5];
for (this->i = 0; this->i < 5; this->i++) {
this->a[this->i] = this->i;
this->b[this->i] = this->i;
}
for (this->i = 0; this->i < 5; this->i++) {
this->c[this->i] = this->a[this->i] + this->b[this->i];
}
delete [] this->a;
delete [] this->b;
delete [] this->c;
}
};
class B : public A {
};
int main() {
B bclass;
bclass.sum();
return 0;
}谢谢
发布于 2011-10-31 21:29:56
在可用的各种选项之间有一个小小的混淆:
-ast-print将漂亮地打印当前的AST,也就是说,它将使它理解的代码尽可能接近于它所解析的代码(但是使某些内容显式,比如this)-ast-dump的幻影将生成当前AST的lisp表示
漂亮的打印机可以用来检查AST是否是无损的(例如,保留这种表达式的const-ness,等等)但这并不是真正的发展。
如果您想破解编译器,则需要-ast-dump,它将生成一个输出,该输出直接映射所解析代码的内存中表示。
发布于 2011-10-29 05:21:07
AST在内存中是一个链接的结构(“树”并不代表事物的复杂性,但它是人们使用的名称)。-ast-print生成的是AST的文本表示。由于设置该选项的人员已经熟悉类似C/C++的语法,因此它以遵循该语法的表示形式打印。这是一个设计选择,而不是一个愉快的巧合。
如果您想要查看不是故意使用熟悉的语法打印的AST是什么样子,例如,您可以查看GIMPLE,这是GCC的内部表示。
发布于 2011-10-29 05:42:35
如果你想玩GIMPLE,你甚至可以使用GCC MELT。MELT是一种处理GIMPLE的高级领域特定语言!
在编译器内部,内部表示通常不是树,而是某种循环结构。在GCC中,基本块知道它是gimple-s,但是gimple-s可能知道他们的基本块...(它有点复杂,但您已经有了想法)。
https://stackoverflow.com/questions/7935008
复制相似问题