#include <stdio.
h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct TAC {
char result[10], op1[10], op[5], op2[10];
} code[10];
int n;
int isNumber(char *s) {
for (int i = 0; s[i]; i++)
if (!isdigit(s[i])) return 0;
return 1;
}
void constantFolding() {
for (int i = 0; i < n; i++) {
if (isNumber(code[i].op1) && isNumber(code[i].op2)) {
int a = atoi(code[i].op1);
int b = atoi(code[i].op2);
int res;
if (strcmp(code[i].op, "+") == 0) res = a + b;
else if (strcmp(code[i].op, "-") == 0) res = a - b;
else if (strcmp(code[i].op, "*") == 0) res = a * b;
else if (strcmp(code[i].op, "/") == 0 && b != 0) res = a / b;
else continue;
sprintf(code[i].op1, "%d", res);
strcpy(code[i].op, "");
strcpy(code[i].op2, "");
}
}
}
void copyPropagation() {
for (int i = 0; i < n; i++) {
if (strcmp(code[i].op, "") == 0 && isNumber(code[i].op1)) {
char old[10];
strcpy(old, code[i].result);
for (int j = i + 1; j < n; j++) {
if (strcmp(code[j].op1, old) == 0)
strcpy(code[j].op1, code[i].op1);
if (strcmp(code[j].op2, old) == 0)
strcpy(code[j].op2, code[i].op1);
}
}
}
}
void printCode(char *title) {
printf("\n%s:\n", title);
for (int i = 0; i < n; i++) {
printf("%s = %s", code[i].result, code[i].op1);
if (strlen(code[i].op) > 0)
printf(" %s %s", code[i].op, code[i].op2);
printf("\n");
}
}
int main() {
printf("Enter no. of statements: ");
scanf("%d", &n);
printf("Enter the 3-address code (result op1 op op2):\n");
printf("Example: t1 = a + b → enter as: t1 a + b\n\n");
for (int i = 0; i < n; i++) {
scanf("%s %s %s %s", code[i].result, code[i].op1, code[i].op, code[i].op2);
}
printCode("After Folding");
constantFolding();
printCode("After Propagation");
copyPropagation();
printCode("After Optimization (Final Code)");
return 0;
}
Explanation:
Command-Line Style Explanation
---
🔹 Line 1–4
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
🧩 Explanation:
stdio.h → for printf() and scanf()
string.h → for string functions (strcpy(), strcmp(), etc.)
stdlib.h → for atoi() (string → integer)
ctype.h → for isdigit() (checks digits)
---
🔹 Line 6–9
struct TAC {
char result[10], op1[10], op[5], op2[10];
} code[10];
🧩 Explanation:
We define a structure to store one line of Three Address Code (TAC).
Example: for t1 = a + b,
→ result = t1, op1 = a, op = +, op2 = b
code[10] → can store up to 10 statements.
---
🔹 Line 11
int n;
🧩 Holds the number of statements entered by the user.
---
🔹 Line 13–17
int isNumber(char *s) {
for (int i = 0; s[i]; i++)
if (!isdigit(s[i])) return 0;
return 1;
}
🧩 Explanation:
Checks if a string is purely numeric.
Used to identify constants like 5 or 10.
Returns 1 → true if all characters are digits, else 0.
---
🔹 Line 19–41 → constantFolding() function
void constantFolding() {
for (int i = 0; i < n; i++) {
if (isNumber(code[i].op1) && isNumber(code[i].op2)) {
int a = atoi(code[i].op1);
int b = atoi(code[i].op2);
int res;
🧩 Checks every line.
If both operands are numbers, it performs the operation immediately.
Example:
t1 = 5 + 4 → directly becomes t1 = 9
if (strcmp(code[i].op, "+") == 0) res = a + b;
else if (strcmp(code[i].op, "-") == 0) res = a - b;
else if (strcmp(code[i].op, "*") == 0) res = a * b;
else if (strcmp(code[i].op, "/") == 0 && b != 0) res = a / b;
🧩 Depending on the operator, it performs arithmetic.
sprintf(code[i].op1, "%d", res);
strcpy(code[i].op, "");
strcpy(code[i].op2, "");
🧩 Stores the result in op1,
clears the operator and operand2 (since it’s now a single constant).
✅ Output example after this step:
t1 = 9
t2 = t1 + 5
---
🔹 Line 43–58 → copyPropagation()
if (strcmp(code[i].op, "") == 0 && isNumber(code[i].op1))
🧩 Finds statements like t1 = 9 (a copy of a constant).
strcpy(old, code[i].result);
for (int j = i + 1; j < n; j++) {
if (strcmp(code[j].op1, old) == 0)
strcpy(code[j].op1, code[i].op1);
if (strcmp(code[j].op2, old) == 0)
strcpy(code[j].op2, code[i].op1);
}
🧩 For every later statement, if it uses t1, replace it with 9.
Example:
Before: t2 = t1 + 5
After : t2 = 9 + 5
✅ This removes unnecessary temporary variable usage.
---
🔹 Line 60–69 → printCode()
void printCode(char *title) {
printf("\n%s:\n", title);
for (int i = 0; i < n; i++) {
printf("%s = %s", code[i].result, code[i].op1);
if (strlen(code[i].op) > 0)
printf(" %s %s", code[i].op, code[i].op2);
printf("\n");
}
}
🧩 This function neatly prints TAC at any stage — with a title like After Folding or After
Propagation.
---
🔹 Line 71–90 → main()
printf("Enter no. of statements: ");
scanf("%d", &n);
🧩 Asks how many TAC lines you’ll enter.
---
printf("Enter the 3-address code (result op1 op op2):\n");
🧩 Informs user about input format.
Example:
t1 5 + 4
---
for (int i = 0; i < n; i++) {
scanf("%s %s %s %s", code[i].result, code[i].op1, code[i].op, code[i].op2);
}
🧩 Reads all your statements one by one.
---
Then step by step:
printCode("After Folding");
constantFolding();
printCode("After Propagation");
copyPropagation();
printCode("After Optimization (Final Code)");
🧩 Calls each function and prints the intermediate result, just like the table in your notebook
photo.
---
🔹 Output Example
Enter no. of statements: 6
Enter the 3-address code (result op1 op op2):
t1 5 + 4
t2 t1 + 5
t3 t2 < t1
t4 t1 + 5
t5 t4 + 0
t6 t3 + t2
Output:
After Folding:
t1 = 9
t2 = t1 + 5
t3 = t2 < t1
t4 = t1 + 5
t5 = t4 + 0
t6 = t3 + t2
After Propagation:
t1 = 9
t2 = 9 + 5
t3 = t2 < 9
t4 = 9 + 5
t5 = t4 + 0
t6 = t3 + t2
After Optimization (Final Code):
t1 = 9
t2 = 9 + 5
t3 = t2 < 9
t4 = t2
t5 = t4 + 0
t6 = t3 + t2