将C程序转换为控制流图的Java代码

发布于 2024-09-06 04:39:24 字数 52 浏览 4 评论 0原文

我需要一个java代码来将C程序转换为控制流图。

有人可以帮我解决一下吗?

I require a java code for converting a C program into a control flow graph.

Can any one please help me out with it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

银河中√捞星星 2024-09-13 04:39:24

7 月 12 日将是一个很难满足的截止日期,但您可以做到。

如果我自己完成这个项目,我将使用以下一般策略:

  1. 预处理输入 C 文件(也称为翻译单元)。这会生成预处理的翻译单元
  2. 将预处理后的翻译单元解析为抽象语法树(AST)。
  3. 遍历 AST,为每个函数声明创建一个图形节点 n。将(函数名称n)添加到地图。
  4. 遍历 AST,构建控制流图。考虑如何在控制流图中表示以下特殊情况:
    • 带标签的语句
    • 如果/else
    • if 后面没有 else
    • 转到
    • 开关
    • switch 内的失败案例和 break
    • 循环,例如 do...whilewhilefor
    • 在循环内中断
    • 在循环内继续
    • 返回
    • 常规函数调用
    • 调用函数指针的目标
    • void 函数定义结束(无返回
    • int main()int main(int, char**) 结束,不需要return
    • 退出
    • 中间值
  5. DOT 中输出图形格式

您可能想使用这个测试程序,我认为它具有所有“特殊”情况:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

void usage(const char *arg0)
{
    fprintf(stderr, "Usage: %s [INTEGER]\n", arg0);
    fprintf(stderr, "Dummy program\n");
    exit(EXIT_FAILURE);
}

int g_a;

void init()
{
    g_a = 3;
}

int return_4()
{
    return 4;
}

void uninit()
{
}

int main(int argc, char **argv)
{
    if (argc <= 1) {
        usage(argv[0]);
    }

    if (argc > 2) {
        printf("You only need to pass one argument.\n");
    }
    else {
        init();
    }

    const int i = atoi(argv[1]);
    int j;
before_switch: j = 0;
switch_i: switch (i) {
        case 3:
            for(; j < 3; ++j)
                printf(".");
        case 17:
            for(; j < 17; ++j)
                printf(".");
            if (i == 3 || i == 17)
                printf("\n");
        case -4:
            printf("You picked one of my favorite numbers (17, 3, and -4)!\n");
            break;

        case -1:
            printf("Cleaning up\n");
            goto cleanup;

        default:
            printf("I don't like that number.\n");
    }

    j = 0;
do_loop_1: do {
        if (j++ % 2 == 0)
            continue;
        if (j == 10)
            break;

        printf("j is %d.\n", j);
    } while(j < 30);

    j = 10;
    while (j > 0) {
        if (4 == return_4())
            break;
        --j;
    }

    void (*voidFn)() = &uninit;
    voidFn();
    init();

cleanup:
    uninit();
    return EXIT_SUCCESS;
}

我还将使用以下开源库:

  1. JCPP,C 预处理器的纯 Java 实现,用于预处理翻译单元
  2. ANTLR 用于与 ANTLR C 语法 一起解析
  3. Grappa 用于图形数据结构和图形绘制(如果需要)

July 12th is going to be a tough deadline to meet, but you can do it.

Here is the general strategy that I would use if I were completing this project myself:

  1. Preprocess the input C file (also called the translation unit). This generates the preprocessed translation unit.
  2. Parse the preprocessed translation unit as an abstract syntax tree (AST).
  3. Traverse the AST, creating a graph node n for each function declaration. Add (function name, n) to a map.
  4. Traverse the AST, building a graph of the control flow. Consider how you are going to represent the following, special cases in the control flow graph:
    • Labelled statements
    • if/else
    • if not followed by else.
    • goto
    • switch
    • Fall-through cases and break within switch.
    • Loops such as do...while, while, and for.
    • break within a loop
    • continue within a loop
    • return
    • Regular function calls
    • Calling the target of a function pointer
    • End of a void function definition (no return)
    • End of int main() and int main(int, char**), which does not require return
    • exit
    • Intermediate values
  5. Output the graph in DOT format.

You may want to use this test program, which I think has all of the "special" cases:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

void usage(const char *arg0)
{
    fprintf(stderr, "Usage: %s [INTEGER]\n", arg0);
    fprintf(stderr, "Dummy program\n");
    exit(EXIT_FAILURE);
}

int g_a;

void init()
{
    g_a = 3;
}

int return_4()
{
    return 4;
}

void uninit()
{
}

int main(int argc, char **argv)
{
    if (argc <= 1) {
        usage(argv[0]);
    }

    if (argc > 2) {
        printf("You only need to pass one argument.\n");
    }
    else {
        init();
    }

    const int i = atoi(argv[1]);
    int j;
before_switch: j = 0;
switch_i: switch (i) {
        case 3:
            for(; j < 3; ++j)
                printf(".");
        case 17:
            for(; j < 17; ++j)
                printf(".");
            if (i == 3 || i == 17)
                printf("\n");
        case -4:
            printf("You picked one of my favorite numbers (17, 3, and -4)!\n");
            break;

        case -1:
            printf("Cleaning up\n");
            goto cleanup;

        default:
            printf("I don't like that number.\n");
    }

    j = 0;
do_loop_1: do {
        if (j++ % 2 == 0)
            continue;
        if (j == 10)
            break;

        printf("j is %d.\n", j);
    } while(j < 30);

    j = 10;
    while (j > 0) {
        if (4 == return_4())
            break;
        --j;
    }

    void (*voidFn)() = &uninit;
    voidFn();
    init();

cleanup:
    uninit();
    return EXIT_SUCCESS;
}

I would also use the following open source libraries:

  1. JCPP, a pure Java implementation of the C preprocessor, for preprocessing the translation unit
  2. ANTLR for parsing along with the ANTLR C grammar
  3. Grappa for the graph data structures and graph drawing (if required)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文