Eclipse CDT解析C / C ++头文件返回空AST

问题描述 投票:2回答:1

我在一个独立的Java应用程序中使用Eclipse CDT作为C / C ++头文件的解析器,其想法是从头部代码生成JNI / JNA绑定。

下载了JAR文件(很难找到,没有这个库的maven!)并解析了一个工作得很好的简单头文件。

然而,当我尝试真正的头文件时,结果有些随机:返回的AST没有子节点,只有一些预处理器声明存在,而且最奇怪的是只检测到两个注释。

这是减少的代码:

    final FileContent content = FileContent.createForExternalFileLocation("C:/VulkanSDK/1.1.101.0/Include/vulkan/vulkan.h");
    final Map<String, String> definedMacros = new HashMap<>();
    definedMacros.put("__cplusplus", "1");
    final String[] includePaths = new String[0];
    final IScannerInfo info = new ScannerInfo(definedMacros, includePaths);
    final IncludeFileContentProvider emptyIncludes = IncludeFileContentProvider.getEmptyFilesProvider();
    final IIndex index = EmptyCIndex.INSTANCE;
    final int options = 0;
    final IParserLogService log = new DefaultLogService();
    final IASTTranslationUnit unit = GPPLanguage.getDefault().getASTTranslationUnit(content, info, emptyIncludes, index, options, log);
    System.out.println("len="+unit.getChildren().length);

我试图解析的头文件是Vulkan图形库,它非常大,所以这里是link,这里是文件的前几位:

#ifndef VULKAN_H_
#define VULKAN_H_ 1

#ifdef __cplusplus
extern "C" {
#endif

/*
** Copyright (c) 2015-2017 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/


#define VK_VERSION_1_0 1
#include "vk_platform.h"

getComments()返回的两条注释是文件顶部的第一个大注释块,奇怪的是:

// VULKAN_H_

即它似乎已经决定预处理器声明是评论!?

虽然解析器接受日志记录回调,但它并没有告诉我任何事情,并且没有报告任何问题。我怀疑有些东西我不了解CDT和预处理器语句,但我找不到任何类似的问题(CDT是一个非常小众的工具)。

我已经摆弄了代码中我能想到的所有内容,包括各种选项参数,但每次都得到相同的结果。正如我所说解析其他更简单的头文件工作得很好。

有任何想法吗?建议?

java eclipse eclipse-cdt
1个回答
0
投票

所以我是个白痴!

而不是解析我认为我正在解析的实际头文件我设法加载'超'头文件,然后#includes我真正想要的文件。这个超级标题包括在平台上切换的各种其他标题,等等,标准方法。我发布的代码没有递归到#included文件,所以结果是正确的空!一旦我将代码指向正确的标题,然后按预期构建AST。

然而,这并没有解释看似随意的评论和奇怪的评论标题后卫 - 我已经向Eclipse CDT开发人员提出了一个问题(尽管我的愚蠢),结果完全让我感到震惊。

对于任何感兴趣的代码生成JNA结构和从头文件中的枚举很好的人(尽管CDT不是这样的'真正的'库)。

这是一个从C typedef enum生成的枚举类示例:

package org.sarge.jove.platform.vulkan;

/**
 * HEADER COMMENT
 */
public enum VkBorderColor {
    VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK(0),     
    VK_BORDER_COLOR_INT_TRANSPARENT_BLACK(1),   
    VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK(2),  
    VK_BORDER_COLOR_INT_OPAQUE_BLACK(3),    
    VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE(4),  
    VK_BORDER_COLOR_INT_OPAQUE_WHITE(5),    
    VK_BORDER_COLOR_BEGIN_RANGE(0),     
    VK_BORDER_COLOR_END_RANGE(5),   
    VK_BORDER_COLOR_RANGE_SIZE(6),  
    VK_BORDER_COLOR_MAX_ENUM(2147483647);   

    private final int value;

    private VkBorderColor(int value) {
        this.value = value;
    }

    /**
     * @return Enum literal
     */
    public int value() {
        return value;
    }
}

使用实际的C / C ++解析器意味着我可以访问实际的枚举值,甚至是表达式的值。

这是一个由C struct生成的JNA结构:

package org.sarge.jove.platform.vulkan;

import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.Pointer;
import org.sarge.jove.platform.vulkan.VkStructureType;

/**
 * HEADER COMMENT
 */
@FieldOrder({
    "sType",
    "pNext",
    "physicalDeviceCount",
    "physicalDevices",
    "subsetAllocation"
})
public class VkPhysicalDeviceGroupProperties extends Structure {
    public static class ByValue extends VkPhysicalDeviceGroupProperties implements Structure.ByValue { }
    public static class ByReference extends VkPhysicalDeviceGroupProperties implements Structure.ByReference { }

    public final int sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES.value();
    public Pointer pNext;
    public int physicalDeviceCount;
    public Pointer[] physicalDevices = new Pointer[32];
    public int subsetAllocation;
}

许多Vulkan结构都有一个sType字段来识别结构的类型(!),所以我可以自动神奇地将字段初始化为相应的生成枚举 - sweet。

再次使用CDT也意味着我可以处理C数组类型的映射和初始化数组字段(JNA内存管理的要求)。

所以最终CDT运作良好。

故事的道德:记住你是个白痴。

© www.soinside.com 2019 - 2024. All rights reserved.