首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clang : AST (抽象语法树)是什么样子的?

Clang : AST (抽象语法树)是什么样子的?
EN

Stack Overflow用户
提问于 2011-10-29 05:16:17
回答 3查看 10.2K关注 0票数 10

嗨,我是编译器开发的新手,我想知道AST是什么样子的。我有一小段代码,并且我使用Clang来生成AST。我从中得不到太多信息。从外观上看,语法树与源代码完全相同,除了添加到我测试的几乎所有样本中的一个结构。

来源:

代码语言:javascript
复制
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的命令:

代码语言:javascript
复制
clang++ -cc1 -ast-print ~/sum.cpp

AST输出:

代码语言:javascript
复制
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;
}

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-31 21:29:56

在可用的各种选项之间有一个小小的混淆:

  • -ast-print将漂亮地打印当前的AST,也就是说,它将使它理解的代码尽可能接近于它所解析的代码(但是使某些内容显式,比如this)
  • -ast-dump的幻影将生成当前AST

的lisp表示

漂亮的打印机可以用来检查AST是否是无损的(例如,保留这种表达式的const-ness,等等)但这并不是真正的发展。

如果您想破解编译器,则需要-ast-dump,它将生成一个输出,该输出直接映射所解析代码的内存中表示。

票数 16
EN

Stack Overflow用户

发布于 2011-10-29 05:21:07

AST在内存中是一个链接的结构(“树”并不代表事物的复杂性,但它是人们使用的名称)。-ast-print生成的是AST的文本表示。由于设置该选项的人员已经熟悉类似C/C++的语法,因此它以遵循该语法的表示形式打印。这是一个设计选择,而不是一个愉快的巧合。

如果您想要查看不是故意使用熟悉的语法打印的AST是什么样子,例如,您可以查看GIMPLE,这是GCC的内部表示。

票数 6
EN

Stack Overflow用户

发布于 2011-10-29 05:42:35

如果你想玩GIMPLE,你甚至可以使用GCC MELT。MELT是一种处理GIMPLE的高级领域特定语言!

在编译器内部,内部表示通常不是树,而是某种循环结构。在GCC中,基本块知道它是gimple-s,但是gimple-s可能知道他们的基本块...(它有点复杂,但您已经有了想法)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7935008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档