如何将未经处理的C / C ++源转换为语法树(以及返回)?

我希望在这之间有一个转换器

#include  #ifdef HAVE_QQQ #include  #endif char* ololize(char* s) { #ifdef HAVE_QQQ return qqq(s); #else return ololo(s); #endif } 

和这样的事情

 (include_angular "ololo.h") (p_ifdef "HAVE_QQQ" (include_angular "qqq.h")) (define_function "ololize" [(ptr char) "s"] (ptr char) (p_ifdef "HAVE_QQQ" (return (qqq s)) :else (return (ololo s))))) 

即将源代码表示为易于管理的树,而不是从编译器的角度来看,而是从程序员的角度来看。

我不希望100%正确的工作,但它应该适用于大多数现有的源文件。 如果我可以将代码“往返”到树和返回,则可以获得奖励积分。

有没有现有的工具或库?

我们的DMS软件再造工具包及其C ++前端可以做到这一点。 DMS提供语言精确的解析(包括处理GCC和MS方言以及C ++ 11),并构建AST。 根据它的配置方式,它还可以构建完整的符号表,目前可以对C ++进行控制流分析(但对于C ++ 11来说还不是很完整)。

内部 AST,DMS可以重新生成合法的源,这将产生相同的编译结果,无论是漂亮打印还是保留空间(“保真模式”)几乎完全正确。 我们也可以要求将AST导出为XML。

对于OP的小程序,这里是直接从我们的GCC4方言解析器呈现为XML的AST(在DMS库中有一个“PrintASTasXML”函数)。 注意AST包含INCLUDE和预处理器条件。

            ololo.h         HAVE_QQQ        qqq.h                      ololize            s                HAVE_QQQ         qqq    s                       ololo    s                         C:/temp/small.cpp   Cpp~GCC4   

它不会完全从XML中往返; 没有预先配置好构建AST的XML阅读器。 但是,DMS是高度可定制的,并且具有XML解析器作为选项; 读取XML树,重新生成C ++ AST,然后调用prettyprinter会很简单。

我不太确定你的意思是“从程序员的角度来管理”。 这是一棵精确的树。 如果它包含太多细节,欢迎您根据需要应用XSLT转换来简化它,但这样做可能会失去语义准确性。 你也可能失去往返的能力。

我们认为不需要这样的XML导出; DMS生态系统的设计为分析/转换程序(包括C ++程序)提供了大量的基础设施; 我们用DMS完成了大量的C ++源代码解析/转换。 因此, 需要进行XML导出以执行有用的操作并不是很高。 无论如何,我们提供它,因为人们总是要求它。 令我们惊讶的是,我们有一些实际使用它的客户。