Intermediate Code Generation in C, with Example

Intermediate code generation is the process of translating the source code of a program into a form that is easier for a compiler to work with. It is typically an intermediate step in the compilation process, where the source code is transformed into a form that is more amenable to optimization and final code generation.

There are many different intermediate representations (IRs) that can be used for intermediate code generation, such as:

  • Abstract Syntax Trees (ASTs): An AST is a tree-like representation of the source code that captures the structure and meaning of the code. ASTs are typically used to represent the structure of programming languages and are often used as an intermediate representation in compilers.
  • Three-Address Code (TAC): TAC is a form of intermediate representation that consists of a sequence of statements that each assign a value to a variable. TAC statements typically have three operands: the destination variable, the left operand, and the right operand.
  • Control Flow Graph (CFG): A CFG is a graph-based representation of the control flow of a program. It captures the relationships between the different parts of a program and can be used to represent the control flow of the program in a more abstract way.
  • Register Transfer Language (RTL): RTL is a form of intermediate representation that represents the program as a series of register transfers. It is typically used to represent the behavior of a program at the instruction level and is often used as an intermediate representation in optimizing compilers.

Example

Implement Intermediate code generation for simple expressions:

#include <stdio.h> 

#include <string.h>

int i = 1, j = 0, no = 0, tmpch = 90;

char str[100], left[15], right[15];

void findopr();

void explore();

void fleft(int);

void fright(int);

struct exp

{

    int pos;

   char op;

} k[15];

void main()

{

    printf("\t\tINTERMEDIATE CODE GENERATION\n\n");

    printf("Enter the Expression :");

    scanf("%s", str);

    printf("The intermediate code:\n");

    findopr();

    explore();

}

void findopr()

{

    for (i = 0; str[i] != '\0'; i++)

        if (str[i] == ':')

        {

            k[j].pos = i;

            k[j++].op = ':';

        }

    for (i = 0; str[i] != '\0'; i++)

        if (str[i] == '/')

        {

           k[j].pos = i;

            k[j++].op = '/';

        }

    for (i = 0; str[i] != '\0'; i++)

        if (str[i] == '*')

        {

            k[j].pos = i;

            k[j++].op = '*';

        }

    for (i = 0; str[i] != '\0'; i++)

        if (str[i] == '+

        {

            k[j].pos = i;

            k[j++].op = '+';

        }

    for (i = 0; str[i] != '\0'; i++)

        if (str[i] == '-')

        {

            k[j].pos = i;

            k[j++].op = '-';

        }

}

void explore()

{

    i = 1;

    while (k[i].op != '\0')

    {

        fleft(k[i].pos);

        fright(k[i].pos);

        str[k[i].pos] = tmpch--;

        printf("\t%c := %s%c%s\t\t", str[k[i].pos], left, k[i].op, right);

        printf("\n");

        i++;

    }

    fright(-1);

    if (no == 0)

    {

        fleft(strlen(str));

        printf("\t%s := %s", right, left);

        exit(0);

    }

    printf("\t%s := %c", right, str[k[--i].pos]);

}

void fleft(int x)

{

    int w = 0, flag = 0;

    x--;

    while (x != -1 && str[x] != '+' && str[x] != '*' && str[x] != '=' && str[x] != '\0' && str[x] != '-' && str[x] != '/' && str[x] != ':')

    {

        if (str[x] != '$' && flag == 0)

        {

            left[w++] = str[x];

            left[w] = '\0';

            str[x] = '$';

            flag = 1;

        }

        x--;

    }

}

void fright(int x)

{

    int w = 0, flag = 0;

    x++;

    while (x != -1 && str[x] != '+' && str[x] != '*' && str[x] != '\0' && str[x] != '=' && str[x] != ':' && str[x] != '-' && str[x] != '/')

    {

        if (str[x] != '$' && flag == 0)

        {

            right[w++] = str[x];

            right[w] = '\0';

            str[x] = '$';

            flag = 1;

        }

        x++;

    }

}{codeBox}

Explanation 

The code first reads an expression as a string and calls the findopr function to locate the operators in the expression. It then stores the position and operator of each operator in a struct called exp.

Next, the explore function is called to process the expression. It loops through the exp struct and for each operator, it calls the fleft and fright functions to determine the left and right operands for the operator. It then generates intermediate code by printing the left operand, operator, and right operand, and storing the result in a temporary variable.

Finally, the result of the expression is stored in the final variable right. If there are no operators in the expression, then the original expression is simply stored in the right.

Conclusion

There are also many programming languages and libraries that allow developers to write code generators or compilers in C. These tools provide APIs and libraries for parsing and analyzing source code, generating intermediate code, and optimizing and transforming the intermediate code into machine code.

Previous Post Next Post
Premium By Raushan Design With Shroff Templates