语法分析器的任务是确定某个单词流是否能够与源语言的语法适配,即设定一个称之为上下文无关语言(context-free language)的语言集合,语法分析器建立一颗与(词法分析出的)输入单词流对应的正确语法树。语法分析树的建立过程主要有两种方法:自顶向下语法分析法和自底向上分析法。AST作为语法分析树(parse tree)的一种简写方式,它独立于具体编程语言(C++、Java、C等),而且与语法分析树的建立过程无关(自顶向下和自底向上逻辑等价),是联系编译器前端、后端的重要接口。Clang的AST树与其他一些AST有些区别,如前者括号表达式为未裁剪模式(in an unreduced form),后者一般会尽量省去多余的括号,这样方便建立重构工具(clang\docs\IntroductionToTheClangAST.rst中说明)。
一、AST的直观印象
可以使用clang –emit-ast input.cpp生成AST的二进制文件input.ast,也可以直接打印输出如下:
参考链接:
http://www.cnblogs.com/zhangke007/p/4714245.html
除了main函数,部分代码:
class Visitor : public RecursiveASTVisitor < Visitor > {
public:
virtual bool VisitDecl(Decl *decl){
if (decl)
cout << "Visit Decl !" << endl;
return true;
}
virtual bool VisitNamedDecl(NamedDecl *decl){
if (decl)
{
cout << "Visit NamedDecl :" << decl->getQualifiedNameAsString() << endl;
}
return true;
}
virtual bool VisitNamespaceDecl(NamespaceDecl *decl){
if (decl){
cout << "Visit NamespaceDecl:" << decl->getQualifiedNameAsString() << endl;
}
return true;
}
};
class MyASTConsumer : public ASTConsumer{
bool HandleTopLevelDecl(DeclGroupRef DR) override{
for (DeclGroupRef::iterator it = DR.begin(); it != DR.end(); ++it){
visitor.TraverseDecl(*it);
(*it)->dump(); //打印AST nodes
}
return true;
}
private:
Visitor visitor;
};
class MyFrontendAction : public ASTFrontendAction{
public:
MyFrontendAction(){}
unique_ptr<ASTConsumer>CreateASTConsumer(CompilerInstance &CI, StringRef file)override{
llvm::errs()<< "Create ASTConsumer for " << file << "\n";
return llvm::make_unique<MyASTConsumer>();
}
};