-3

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

Can any one please help me out with it?

Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193

1 Answers1

2

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)
Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193
  • 1
    Your example doesn't cover the nasty things you can write in C. It is perfectly legal to put a label in the middle of a block, and **goto** it from outside the block. It is perfectly legal to put a build switch statments whose cases are not well structured. In Gcc, you have goto indirect. Most versions of C allow setjmp. All of these can make what appear to be structured program into a spaghetti tangle. – Ira Baxter Jun 22 '10 at 14:19
  • @Ira: True. I had forgotten about these features of C. Hopefully, though, following this strategy will yield a program that *could* handle these additional cases. – Daniel Trebbien Jun 23 '10 at 23:31