7

我有一个 C++ 应用程序,我也有它的源代码,它是基于 .Net 框架构建的。我现在正在寻找的是一种工具(理想情况下是免费的),它可以将我的源代码作为输入,并且经过一些预处理或一些必需的编程后,可以为我提供源代码元素的结构依赖性的中间表示,例如 AST 或调用图。我正在使用 java 来检查这个 C++ 源代码,所以如果解决方案是在 java 环境中,比如 eclipse 的插件或其他东西,那就更好了。有没有适合我需要的可用工具?谢谢你们。

4

6 回答 6

4

你可能对 doxygen 感兴趣,它是一个基于源代码生成文档的免费工具。无需任何额外工作,您就可以生成调用图、继承图、协作图和许多其他有用的工具。

http://www.doxygen.nl/

于 2012-10-12T19:17:35.687 回答
4

我已经使用 NetBeans 的 CND 模块成功地解析了 Java 中的 C++。它仍然丑陋,但可能比使用原始 ANTLR 或其他更好。首先,为简单起见,从http://netbeans.org/downloads/zip.html下载“all-in-one”包(CND 实际上并不需要所有这些类)并将其解压缩到当前目录中的某个位置。接下来,这是我一直在玩的一个玩具 C++ 头文件:

namespace foo {

int f(int p);

template<typename A> class bar {
    void run(A) { }
};

}

这是我用 CND 解析它的尝试:

import java.io.*;
import java.util.*;
import org.openide.filesystems.*;
import org.netbeans.modules.cnd.api.model.*;
import org.netbeans.modules.cnd.api.model.services.*;
import org.netbeans.modules.cnd.modelimpl.csm.*;

public class Foo {
    public static void main(String[] args) throws Exception {
        FileObject fo = FileUtil.toFileObject(new File(args[0]));
        CsmStandaloneFileProvider fp = CsmStandaloneFileProvider.getDefault();
        CsmModel model = CsmModelAccessor.getModel();
        CsmModelState modelState = CsmModelAccessor.getModelState();

        CsmFile cf = fp.getCsmFile(fo);
        cf.scheduleParsing(true);
        Collection<CsmOffsetableDeclaration> c = cf.getDeclarations();
        c = ((CsmNamespaceDefinition)c.toArray()[0]).getDeclarations();
        for (CsmOffsetableDeclaration d : c) {
            if (d instanceof CsmFunction) {
                CsmFunction f = (CsmFunction)d;
                System.out.print(f.getQualifiedName() + " " + f.getName() + "(");
                Collection<CsmParameter> pp = f.getParameters();
                for (CsmParameter p : pp) {
                    System.out.print(p.getType().getClassifierText());
                }
                System.out.println(")");
            } else if (d instanceof ClassImpl) {
                ClassImpl cls = (ClassImpl)d;
                System.out.println("Got template? " + cls.isTemplate());
                List<CsmTemplateParameter> lt = cls.getTemplateParameters();
                for (CsmTemplateParameter t : lt) {
                    System.out.println(t.getQualifiedName() + " " + t.getName());
                }
                Collection<CsmMember> cm = cls.getMembers();
                for (CsmMember m : cm) {
                    CsmFunction f = (CsmFunction)m;
                    System.out.print(f.getQualifiedName() + " " + f.getName() + "(");
                    Collection<CsmParameter> pp = f.getParameters();
                    for (CsmParameter p : pp) {
                        System.out.print(p.getType().getClassifierText());
                    }
                    System.out.println(")");
                }
            }
        }
    }
}

我们需要添加到类路径中的 JAR 文件的数量非常大,并且必须有更好的方法来处理这个问题,但目前这可行:

$ export CLASSPATH=netbeans/platform/modules/org-netbeans-modules-editor-mimelookup.jar:netbeans/platform/modules/org-netbeans-modules-queries.jar:netbeans/dlight/modules/org-netbeans-modules-dlight-libs-common.jar:netbeans/ide/modules/org-netbeans-modules-projectapi.jar:netbeans/platform/modules/org-netbeans-api-progress.jar:netbeans/platform/modules/org-openide-windows.jar:netbeans/platform/modules/org-openide-text.jar:netbeans/platform/modules/org-openide-awt.jar:netbeans/platform/lib/org-openide-modules.jar:netbeans/platform/modules/org-openide-nodes.jar:netbeans/platform/modules/org-netbeans-modules-masterfs.jar:netbeans/platform/core/org-openide-filesystems.jar:netbeans/platform/lib/org-openide-util.jar:netbeans/platform/lib/org-openide-util-lookup.jar:netbeans/platform/modules/org-openide-loaders.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-api-model.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-api-project.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-model-services.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-modelimpl.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-modelutil.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-utils.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-repository.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-repository-api.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-apt.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-source.jar:netbeans/cnd/modules/org-netbeans-modules-cnd-antlr.jar:.
$ javac Foo.java
$ java Foo Foo.h

并输出以下内容:

foo::f f(int)
Got template? true
foo::bar::A A
foo::bar::run run(A)

顺便说一句,我们可以用 Eclipse CDT 做类似的事情: Parsing / reading C-Header files using Java

于 2012-10-13T06:54:58.480 回答
1

您可以使用以纯Java实现且只有 2 个 jar的Eclipse Parser 。我已经给出了如何使用的详细信息,请参见链接:https ://stackoverflow.com/a/27496664/955857

上面的链接还有一个项目,它对 Eclipse Parser 进行了抽象,带来了更简单的结构(但并不适合所有情况)

于 2014-12-16T02:54:41.657 回答
0

根据您的要求,您可能会对 Synopsis 感兴趣:http ://synopsis.fresco.org/

这是一个解析源代码(C/C++/Python/IDL)并生成抽象语法图的模块化工具。该图可以通过 API 进行遍历(例如,也可以将其传递给其他概要模块以生成源文档)。Synopsis 提供 C++ 和 Python API,不幸的是没有 Java API - 但我想它可以通过 Jython(当然也可以是 JNI ;-) 从 Java 中使用)

于 2012-10-12T19:35:09.170 回答
0

我认为你应该看看 Xogastan。它将 C++ 的 AST 生成为 XML 文档。Xogastan 有很多选择。

索加斯坦之家

问候,

编辑:它不直接与 Java 连接,但您可以将其用作外部工具,然后分析生成的 XML。

于 2012-10-12T19:39:40.073 回答
0

塞缪尔·奥德特是对的!但他缺少 JAR 文件。您需要添加以下 JAR 文件:org-netbeans-modules-cnd-indexing.jar、org-netbeans-modules-parsing-lucene.jar、org-netbeans-libs-lucene.jar 和 lucene-core-3.5.0 。罐。

于 2013-08-10T05:11:29.570 回答