You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Clang Python绑定解析含OpenACC的C/C++ AST并生成JSON

Solution for Parsing OpenACC Directives to JSON

Prerequisites

First, install the required Clang Python bindings:

pip install clang

Note: You'll need a local LLVM installation (version 12+ recommended). Adjust the library path in the script to match your LLVM setup.

Python Script

import clang.cindex
import json
from clang.cindex import CursorKind

# Configure Clang library path (update this to your LLVM installation path)
clang.cindex.Config.set_library_path('/usr/lib/llvm-14/lib')
index = clang.cindex.Index.create()

def get_cursor_text(cursor):
    """Extract raw source text from a given AST cursor"""
    return cursor.extent.source.get_bytes().decode('utf-8').strip()

def collect_openacc_pairs(node, directive_pairs):
    # Check for OpenACC attributes attached to the current node
    for attr in node.get_children():
        if attr.kind == CursorKind.ATTRIBUTE and 'acc_' in attr.spelling:
            # Traverse up to find the code block the directive applies to
            target_node = node
            valid_target_kinds = [
                CursorKind.COMPOUND_STMT, CursorKind.FOR_STMT,
                CursorKind.WHILE_STMT, CursorKind.DO_STMT, CursorKind.IF_STMT
            ]
            while target_node.kind not in valid_target_kinds and target_node.parent:
                target_node = target_node.parent
            
            # Add the directive-code block pair to our list
            directive_pairs.append({
                "directive_type": attr.spelling.replace('acc_', 'acc '),
                "directive_text": get_cursor_text(attr),
                "code_block": get_cursor_text(target_node)
            })
    
    # Recurse into child nodes to find more directives
    for child in node.get_children():
        collect_openacc_pairs(child, directive_pairs)

if __name__ == "__main__":
    input_file = "sample_openacc_code.c"  # Replace with your input file path
    # Parse with OpenACC support enabled
    translation_unit = index.parse(
        input_file,
        args=['-x', 'c', '-std=c11', '-fopenacc']
    )
    
    directive_pairs = []
    collect_openacc_pairs(translation_unit.cursor, directive_pairs)
    
    # Write results to JSON
    with open("openacc_directive_map.json", "w") as outfile:
        json.dump(directive_pairs, outfile, indent=4)
    
    print(f"Generated JSON with {len(directive_pairs)} directive-code block pairs")

Sample Input & Output

Sample OpenACC Code (sample_openacc_code.c)

#include <stdio.h>

int main() {
    int arr[100];
    int i;

    #pragma acc parallel loop
    for (i = 0; i < 100; i++) {
        arr[i] = i * 2;
    }

    #pragma acc data copy(arr)
    {
        #pragma acc kernels
        for (i = 0; i < 100; i++) {
            arr[i] += 1;
        }
    }

    return 0;
}

Sample Output JSON (openacc_directive_map.json)

[
    {
        "directive_type": "acc parallel_loop",
        "directive_text": "#pragma acc parallel loop",
        "code_block": "for (i = 0; i < 100; i++) {\n        arr[i] = i * 2;\n    }"
    },
    {
        "directive_type": "acc data",
        "directive_text": "#pragma acc data copy(arr)",
        "code_block": "{\n        #pragma acc kernels\n        for (i = 0; i < 100; i++) {\n            arr[i] += 1;\n        }\n    }"
    },
    {
        "directive_type": "acc kernels",
        "directive_text": "#pragma acc kernels",
        "code_block": "for (i = 0; i < 100; i++) {\n            arr[i] += 1;\n        }"
    }
]

Key Explanations

  • Clang AST Parsing: Clang natively supports OpenACC and represents directives as AST attributes, making it reliable for accurate parsing.
  • AST Traversal: The script recursively walks the AST to locate OpenACC attributes, then maps each to its associated code block by traversing up to valid statement types.
  • Text Extraction: Uses cursor extents to pull the exact source text of both directives and their target code blocks.

Relevant Learning Resources

  • Clang Python Bindings: Learn to navigate AST nodes, cursor types, and attribute handling to extend the script for complex cases.
  • OpenACC Specification: Understand directive syntax and scope rules to refine how you map directives to code blocks.
  • Clang AST Reference: Familiarize yourself with Clang's AST node hierarchy to handle edge cases like nested directives or conditional code blocks.
  • Python JSON Module: Master serialization options to customize the output format as needed.

内容的提问来源于stack exchange,提问作者Samyak Jhaveri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:50:17