0% found this document useful (0 votes)
24 views66 pages

CD Record

Uploaded by

Mani Raj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views66 pages

CD Record

Uploaded by

Mani Raj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 66

18CSE304J

COMPILER DESIGN
SEMESTER - VI

NAME : MUHAMMAD RISHAN


REG.NO : RA2111003040137

2023 - 2024

DEPARTMENT OF COMPUTER SCIENCE AND


ENGINEERING

SRM INSTITUTE OF SCIENCE AND TECHNOLOGY


VADAPALANI CAMPUS

CHENNAI - 600 026

1
BONAFIDE CERTIFICATE

This is to certify that the bonafide record work done by Muhammad


Rishan_Register Number RA2111003040137 of B.Tech - Computer
Science and Engineering, Third Year, VI Semester for the Laboratory of
the course 18CSC304J - COMPILER DESIGN during the academic year
2023 - 2024.

Lab in charge Head of the Department

Submitted for the University Examination held on at


SRM INSTITUTE OF SCIENCE AND TECHNOLOGY, Vadapalani.

Date: Examiner - I Examiner - II

2
INDEX

Experiment Date Experiment Name Page


No. Number Sign

1 29/01/24 Implementation Of Lexical 1


Analyzer
Conversion From Regular
2 29/01/24 7
Expression To
NFA

3 05/02/24 Conversion From DFA To NFA 10

4 12/02/24 Left Factoring, Left Recursion 15

5 12/02/24 FIRST AND FOLLOW 20


Computations

6 19/02/24 Predictive Parsing Table 24

7 26/02/24 Shift Reducing Parser 27

Computation Of LEADING
8 04/03/24 31
AND TRAILING

9 09/03/24 Computation Of LR(0) Items 36

Intermediate Code Generation -


10 18/03/24 40
Postfix, Prefix
Intermediate Code Generation -
11 25/03/24 44
Three Address

12 25/03/24 A Simple Code Generator 49

13 02/04/24 Implementation Of DAG 52

14 10/04/24 Implementation Of Data Flow 56


Analysis
Implementation Of Storage
15 18/04/24 58
Allocation
Strategies
3
Expt. No: 1
Date: 12/01/24 Implementation of Lexical Analyzer

Aim: To write and execute a C program to implement a lexical analyzer.

Algorithm:

1. Start the program

2. Include the header files.

3. Allocate memory for the variable by dynamic memory allocation function.

4. Use the file accessing functions to read the file.

5. Get the input file from the user.

6. Separate all the file contents as tokens and match it with the functions.

7. Define all the keywords in a separate file and name it as key.c

8. Define all the operators in a separate file and name it as open.c

9. Give the input program in a file and name it as input.c

10. Finally print the output after recognizing all the tokens.

11. Stop the program.

Program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int isKeyword(char buffer[]) {


char keywords[32][10] = {
"auto", "break", "case", "char", "const",
"continue", "default", "do", "double", "else",
"enum", "extern", "float", "for", "goto",
"if", "int", "long", "register", "return",
"short", "signed", "sizeof", "static", "struct",

4
"switch", "typedef", "union", "unsigned", "void",
"volatile", "while"
};

int i, flag = 0;
for(i = 0; i < 32; ++i) {
if(strcmp(keywords[i], buffer) == 0) {
flag = 1;
break;
}
}
return flag;
}

int isInteger(char *str)


{ int i, len =
strlen(str); if(len ==
0) return 0;

for(i = 0; i < len; i++) {


if(!isdigit(str[i]))
return 0;
}
return 1;
}

int isIdentifier(char *str) {


if(isdigit(str[0])) return 0;
return 1;
}

int main() {
char ch, buffer[15];
FILE *fp;
int i, j = 0;

fp = fopen("E:\\program.txt", "r");
if(fp == NULL) {
printf("Error while opening the file\n");
exit(0);
}

while((ch = fgetc(fp)) != EOF) {


for(i = 0; i < 10; ++i) {
if(ch == "+-*/%=!<>"[i])
printf("%c is operator\n", ch);
}

5
if(isalnum(ch)) {
buffer[j++] = ch;
} else if((ch == ' ' || ch == '\n') && (j != 0))
{ buffer[j] = '\0';
j = 0;

if(isInteger(buffer) == 1) {
printf("%s is Integer\n", buffer);
} else if(isKeyword(buffer) == 1) {
printf("%s is keyword\n", buffer);
} else if(isIdentifier(buffer) == 1) {
printf("%s is identifier\n", buffer);
}
}
}
fclose(fp);
return 0;

Output:

Result: C program to implement a lexical analyzer was written and executed successfully.

6
Expt. No: 2
Date: 29/01/24 Conversion from Regular Expression to NFA

Aim: To write and execute a C program to convert the given regular expression to NFA.

Algorithm:

1. Start the program.


2. Declare all necessary header files.
3. Define the main function.
4. Declare the variables and initialize variables r & c to ‘0’.
5. Use a for loop within another for loop to initialize the matrix for NFA states.
6. Get a regular expression from the user & store it in ‘m’.
7. Obtain the length of the expression using strlen() function and store it in ‘n’.
8. Use for loop upto the string length and follow steps 8 to 12.
9. Use switch case to check each character of the expression
10. If case is ‘*’, set the links as ‘E’ or suitable inputs as per rules.
11. If case is ‘+’, set the links as ‘E’ or suitable inputs as per rules.
12. Check the default case, i.e.,for single alphabet or 2 consecutive alphabets and
set the links to respective alphabet.
13. End the switch case.
14. Use for loop to print the states along the matrix.
15. Use a for loop within another for lop and print the value of respective links.
16. .Print the states start state as ‘0’ and final state.
17. .End the program.

Program:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>

7
int ret[100];
static int pos = 0;
static int sc = 0;

void nfa(int st, int p, char *s) {


int i, sp, fs[15], fsc = 0;
sp = sc;
sp = st;
pos = p;
sc = st;

while (*s != '\0') {


if (isalpha(*s)) {
ret[pos++] = sp;
ret[pos++] = *s;
ret[pos++] = ++sc;
} else if (*s == '.') {
ret[pos++] = sc;
ret[pos++] = 238;
ret[pos++] = ++sc;
sp = sc;
} else if (*s == '|') {
sp = st;
fs[fsc++] = sc;
} else if (*s == '*') {
ret[pos++] = sc;
ret[pos++] = 238;
ret[pos++] = sp;
ret[pos++] = sp;
ret[pos++] = 238;
ret[pos++] = sc;

8
} else if (*s == '(') {
char ps[50];
int i = 0, flag = 1;
s++;
while (flag != 0) {
ps[i++] = *s;
if (*s == '(')
flag++;
if (*s == ')')
flag--;
s++;
}
ps[--i] = '\0';
nfa(sc, pos, ps);
s--;
for (i = 0; i < fsc; i++) {
ret[pos++] = fs[i];
ret[pos++] = 238;
ret[pos++] = sc;
}
ret[pos++] = sc - 1;
ret[pos++] = 238;
ret[pos++] = sc;
}
s++;
}
}

int main() {
int i;
char *inp;
char inpp[100];

9
printf("Enter the regular expression: ");
scanf("%s", inpp);
inp = inpp;
nfa(1, 0, inp);
printf("\nState Input State\n");
for (i = 0; i < pos; i = i + 3)
printf("%d --%c--> %d\n", ret[i], ret[i + 1], ret[i + 2]);
printf("\n");
getch();
return 0;
}

Output:

Result: Thus the C program to convert a regular expression to NFA was executed and verified
successfully.

10
Expt. No: 3
Date: 05/02/24 Conversion from NFA to DFA

Aim: To write and execute a C program to convert the given NFA to DFA

Algorithm:

1. Start the program


2. Assign an input string terminated by end of file, DFA with start
3. The final state is assigned to F
4. Assign the state to S
5. Assign the input string to variable C
6. While C!=e of do
S = move(s,c)
C = next char
7. If it is in ten return yes else no
8. Stop the program

Program:

#include <stdio.h>
#include <string.h>

#define STATES 256


#define SYMBOLS 20

int N_symbols;
int NFA_states;
char *NFAtab[STATES][SYMBOLS];
int DFA_states; /* number of DFA states */
int DFAtab[STATES][SYMBOLS];

/* Function Prototypes */
void put_dfa_table(int tab[][SYMBOLS], int nstates, int nsymbols);
void init_NFA_table();
void string_merge(char *s, char *t);
void get_next_state(char *nextstates, char *cur_states, char *nfa[STATES][SYMBOLS], int
n_nfa, int symbol);
int state_index(char *state, char statename[][STATES], int *pn);
int nfa_to_dfa(char *nfa[STATES][SYMBOLS], int n_nfa, int n_sym, int dfa[][SYMBOLS]);

11
/* Print state-transition table. */
void put_dfa_table(int tab[][SYMBOLS], int nstates, int nsymbols) {
int i, j;
puts("STATE TRANSITION TABLE");

/* input symbols: '0', '1', ... */


printf(" | ");
for (i = 0; i < nsymbols; i++)
printf(" %c ", '0' + i);

printf("\n +--");

for (i = 0; i < nsymbols; i++)


printf(" ");
printf("\n");

for (i = 0; i < nstates; i++) {


printf(" %c | ", 'A' + i); /* state */
for (j = 0; j < nsymbols; j++)
printf(" %c ", 'A' + tab[i][j]);
printf("\n");
}
}

/* Initialize NFA table. */


void init_NFA_table() {
NFAtab[0][0] = "2";
NFAtab[0][1] = "";
NFAtab[1][0] = "";
NFAtab[1][1] = "02";
NFAtab[2][0] = "01";
NFAtab[2][1] = "0";

NFA_states = 3;
DFA_states = 0;
N_symbols = 2;
}

/* String 't' is merged into 's' in alphabetical order. */


void string_merge(char *s, char *t) {
char temp[STATES], *r = temp, *p = s;

while (*p && *t) {


if (*p == *t) {
*r++ = *p++;
t++;

12
} else if (*p < *t) {
*r++ = *p++;
} else
*r++ = *t++;
}
*r = '\0';
if (*p)
strcat(r, p);
else if (*t)
strcat(r, t);
strcpy(s, temp);
}

/* Get next-state string for current-state string. */


void get_next_state(char *nextstates, char *cur_states, char *nfa[STATES][SYMBOLS], int
n_nfa, int symbol) {
int i;
char temp[STATES];

temp[0] = '\0';
for (i = 0; i < strlen(cur_states); i++)
string_merge(temp, nfa[cur_states[i] - '0'][symbol]);
strcpy(nextstates, temp);
}

int state_index(char *state, char statename[][STATES], int *pn) {


int i;
if (!*state)
return -1; /* no next state */
for (i = 0; i < *pn; i++)
if (!strcmp(state, statename[i]))
return i;
strcpy(statename[i], state); /* new state-name */
return (*pn)++;
}

/* Convert NFA table to DFA table. Return value: number of DFA states. */
int nfa_to_dfa(char *nfa[STATES][SYMBOLS], int n_nfa, int n_sym, int dfa[][SYMBOLS]) {
char statename[STATES][STATES];
int i = 0; /* current index of DFA */
int n = 1; /* number of DFA states */
char nextstate[STATES];
int j;

strcpy(statename[0], "0"); /* start state */


for (i = 0; i < n; i++) { /* for each DFA state */

13
for (j = 0; j < n_sym; j++) { /* for each input symbol */
get_next_state(nextstate, statename[i], nfa, n_nfa, j);
dfa[i][j] = state_index(nextstate, statename, &n);
}
}
return n; /* number of DFA states */
}

int main() {
init_NFA_table();
DFA_states = nfa_to_dfa(NFAtab, NFA_states, N_symbols, DFAtab);
put_dfa_table(DFAtab, DFA_states, N_symbols);
return 0;
}

Output:

Result: Thus the C program to convert a NFA to DFA was executed and verified successfully.

14
Expt. No: 4
Date: 12/02/24 Elimination of Ambiguity, Left Recursion and Left Factoring

Aim: To write and execute a C program to eliminate left recursion and left factoring in an input
grammar.

Algorithm:

For Left Recursion:

1. For each nonterminal :

a. Repeat until an iteration leaves the grammar unchanged:


b. For each rule , being a sequence of terminals and non terminals.

2. If begins with a nonterminal and :

a. Let be without its leading.


b. Remove the rule .
c. For each rule :
d. Add the rule .

3. Remove direct left recursion for as described above.

For Left Factoring:

1. For each non terminal A find the longest prefix α


common to two or more of its alternatives.
2. If α!= E,i. e., there is a non trivial common prefix, replace all the
A productions. 3. A-> αβ1| αβ2|..............| αβn| ɣ where ɣ represents all
alternatives that do not begin with α by
4. A==> α A’| ɣ
5. A’==>β1|β2|… |βn
6. Here A’ is new non terminal. Repeatedly apply this transformation
until no two alternatives for a non-terminal have a common prefix.

15
Program:

Left Recursion:

#include<stdio.h>
#include<string.h>

// Program in C to remove left recursion from given grammar

int main() {
int i, j, n, k;
int lrec = 0;
char prod[100];
char newprod1[100] = "";
char newprod2[100] = "";

char alpha[100] = "";


char beta[100] = "";
char sts[20] = "";

printf("Enter the production: ");


scanf("%s", prod);
sts[0] = prod[0]; // sts is Start Symbol
int size = strlen(prod);

for (i = 0; i < size; i++) {


if (prod[i] == '|') {
k = i;
}
}

if (prod[3] == prod[0]) {
lrec = 1;
}

if (lrec == 1)
{ int c = 0;
k = k - 1;
for (i = 4; i <= k; i++)
{ alpha[c] = prod[i];
c++;
}
c = 0;
for (i = k + 2; i < size; i++) {
beta[c] = prod[i];

16
c++;
}

strcat(newprod1, sts);
strcat(newprod1, "->");
strcat(newprod1, beta);
strcat(newprod1, sts);
strcat(newprod1, "'");

strcat(newprod2, sts);
strcat(newprod2, "'");
strcat(newprod2, "->");
strcat(newprod2, alpha);
strcat(newprod2, sts);
strcat(newprod2, "'");
strcat(newprod2, "|e");

printf("\n%s\n%s", newprod1, newprod2);


}

return 0;
}

Left Factoring:

#include<stdio.h>
#include<string.h>

int main() {
char a[50], a1[25], a2[25], a3[25], a4[25], a5[25];
int i, j = 0, k = 0, l = 0;

printf("Enter production S->");


fgets(a, sizeof(a), stdin);

for (i = 0; a[i] != '|'; i++, j++)


a1[j] = a[i];
a1[j] = '\0';

for (j = ++i, i = 0; a[j] != '\0'; j++, i++)


a2[i] = a[j];
a2[i] = '\0';

for (i = 0; i < strlen(a1) && i < strlen(a2); i++) {


if (a1[i] == a2[i]) {

17
a3[k++] = a1[i];
} else {
a4[l] = a1[i];
a5[l] = a2[i];
l++;
}
}

a3[k] = 'X';
a3[++k] = '\0';
a4[l] = '|';
a4[++l] = '\0';
a5[l] = '\0';

strcat(a4, a5);

printf("\nAfter Left Factoring:\n");


printf("\n S->%s", a3);
printf("\n X->%s", a4);

return 0;
}

Output:

18
Result: Thus, the C programs to eliminate left factoring and Left recursion has been executed
and the output has been verified successfully.

19
Expt. No: 5
Date: 12/02/24 FIRST AND FOLLOW Computation

Aim: To write a program for first and follow computation in C.

Algorithm:

1. For each terminal


symbol Z
FIRST([Z] « {Z}
2. repeat
3. For each production X —Y, ... ¥,
if ¥, ... Y, areall nullable
(orif k=0) then nullable| X |
< true
4. For each i from 1 to k,each jfrom
i+l to k if Y, ... Y, are all nullable
(or if i=1)
then FIRST[X | < FIRST[X |U FIRSTIY, ]
if Y, ... Y, areall nullable (or if i=k)
then FOLLOW|Y,] <~ FOLLOW|Y,|
u
FOLLOW|X | if Y., ... Y, areall nullable (or if
i+1=j)
then FOLLOWLY, | <~ FOLLOW[Y,]1U FOLLOW[Y,]
5. until FIRST, FOLLOW and nullable no longer change.
Program:
#include<stdio.h>
#include<string.h>
#include<ctype.h>

int n, m = 0, p, i = 0, j = 0;
char a[10][10], f[10];

void follow(char c);


void first(char c);

int main() {
20
21
int i, z;
char c, ch;

printf("Enter the number of productions:\n");


scanf("%d", &n);
printf("Enter the productions:\n");
for(i = 0; i < n; i++)
scanf("%s%c", a[i], &ch);

do {
m = 0;
printf("Enter the element whose first & follow is to be found:");
scanf(" %c", &c);

first(c);
printf("First(%c)={", c);
for(i = 0; i < m; i++)
printf("%c", f[i]);
printf("}\n");

strcpy(f, " ");


m = 0;
follow(c);
printf("Follow(%c)={", c);
for(i = 0; i < m; i++)
printf("%c", f[i]);
printf("}\n");

printf("Continue(0/1)?");
scanf("%d%c", &z, &ch);
} while(z == 1);

return 0;
}

22
void first(char c) {
int k;
if (!isupper(c))
f[m++] = c;
for (k = 0; k < n; k++) {
if (a[k][0] == c) {
if (a[k][2] == '$')
follow(a[k][0]);
else if (islower(a[k][2]))
f[m++] = a[k][2];
else
first(a[k][2]);
}
}
}

void follow(char c) {
if (a[0][0] == c)
f[m++] = '$';
for (i = 0; i < n; i++) {
for (j = 2; j < strlen(a[i]); j++) {
if (a[i][j] == c) {
if (a[i][j + 1] != '\0')
first(a[i][j + 1]);
if (a[i][j + 1] == '\0' && c != a[i][0])
follow(a[i][0]);
}
}
}
}

23
Output :

Result: Thus, the C program for First and Follow Computation has been executed and the output
has been verified successfully.

24
Expt. No: 6
Date: 19/02/24 Predictive Parsing Table

Aim: To write a program for Predictive Parsing Table in C

Algorithm:

1. In the beginning, the pushdown stack holds the start symbol of the grammar G.
2. At each step a symbol X is popped from the stack:
if X is a terminal then it is matched with the lookahead and lookahead is
advanced one step,
if X is a nonterminal symbol, then using lookahead and a parsing table
(implementing the FIRST sets) a production is chosen and its right-hand side is
pushed into the stack.
3. This process repeats until the stack and the input string become null (empty).

Program:

#include<stdio.h>
#include<string.h>

char prol[7][10]={"S","A","A","B","B","C","C"};
char pror[7][10]={"A","Bb","Cd","aB","@","Cc","@"};
char prod[7][10]={"S->A","A->Bb","A->Cd","B->aB","B->@","C->Cc","C->@"};
char first[7][10]={"abcd","ab","cd","a@","@","c@","@"};
char follow[7][10]={"$","$","$","a$","b$","c$","d$"};
char table[5][6][10];

int numr(char c) {
switch(c) {
case 'S': return 0;
case 'A': return 1;
case 'B': return 2;
case 'C': return 3;
case 'a': return 0;
case 'b': return 1;
case 'c': return 2;
case 'd': return 3;
case '$': return 4;
default: return 5; // Default case to handle characters not specified in the switch case
25
26
}
}

int main() {
int i,j,k;

printf("\nThe following is the predictive parsing table for the following grammar:\n");
for(i=0;i<7;i++)
printf("%s\n",prod[i]); printf("\
nPredictive parsing table is\n");

for(i=0;i<7;i++) {
k = strlen(first[i]);
for(j=0;j<10;j++)
if(first[i][j] != '@') strcpy(table[numr(prol[i][0])+1]
[numr(first[i][j])+1], prod[i]);
}

for(i=0;i<7;i++) {
if(strlen(pror[i]) == 1) {
if(pror[i][0] == '@') {
k = strlen(follow[i]);
for(j=0;j<k;j++)
strcpy(table[numr(prol[i][0])+1][numr(follow[i][j])+1], prod[i]);
}
}
}

strcpy(table[0][0]," ");
strcpy(table[0][1],"a");
strcpy(table[0][2],"b");
strcpy(table[0][3],"c");
strcpy(table[0][4],"d");
strcpy(table[0][5],"$");
strcpy(table[1][0],"S");
strcpy(table[2][0],"A");
strcpy(table[3][0],"B");
strcpy(table[4][0],"C");

printf("\n\t\n");
for(i=0;i<5;i++) {
27
for(j=0;j<6;j++) {
printf("%-10s",table[i][j]);
if(j==5)
printf("\n\t\n");
}
}

return 0;
}

Output:

Result: Thus, the C program for Predictive Parsing Table has been executed and the output has
been verified successfully.

28
Expt. No: 7
Date: 26/02/24 Shift Reducing Parser

Aim: To write a program for Shift Reduce Parsing in C.

Algorithm:

1. Initialize the parse stack to contain a single state s0, where s0 is the distinguished initial
state of the parser.
2. Use the state s on top of the parse stack and the current lookahead t to consult the action
table entry action[s][t]:
• If the action table entry is shift s' then push state s' onto the stack and advance the
input so that the lookahead is set to the next token.
• If the action table entry is reduce r and rule r has m symbols in its RHS, then pop
m symbols off the parse stack. Let s' be the state now revealed on top of the parse
stack and N be the LHS nonterminal for rule r. Then consult the goto table and
push the state given by goto[s'][N] onto the stack. The lookahead token is not
changed by this step.
• If the action table entry is accept, then terminate the parse with success.
• If the action table entry is error, then signal an error.
3. Repeat step (2) until the parser terminates.

Program:

#include<stdio.h>
#include<string.h>

int k=0,z=0,i=0,j=0,c=0;
char a[16],ac[20],stk[15],act[10];

int check();

int main() {
puts("GRAMMAR is S->E\n E->E+E \n E->E*E \n E->a \n E->id");
puts("Enter input string:");
fgets(a, sizeof(a), stdin);
c = strlen(a);

strcpy(act,"SHIFT->");
puts("stack \t input \t action");
29
for(k = 0, i = 0, j = 0; j < c; k++, i++, j++) {
if(a[j] == 'i' && a[j+1] == 'd') {
stk[i] = a[j];
stk[i+1] = a[j+1];
stk[i+2] = '\0';
a[j] = ' ';
a[j+1] = ' ';
printf("\n$%s\t%s$\t%sid",stk,a,act);
check();
} else {
stk[i] = a[j];
stk[i+1] = '\0';
a[j] = ' ';
printf("\n$%s\t%s$\t%ssymbols",stk,a,act);
check();
}
}
return 0;
}

int check() {
strcpy(ac,"REDUCE TO E");

for(z = 0; z < c; z++) {


if(stk[z] == 'i' && stk[z+1] == 'd') {
stk[z] = 'E';
stk[z+1] = '\0'; printf("\n$%s\t%s$\t
%s",stk,a,ac); j++;
}
}

for(z = 0; z < c; z++) {


if(stk[z] == 'E' && stk[z+1] == '+' && stk[z+2] == 'E')
{ stk[z] = 'E';
stk[z+1] = '\0';
stk[z+2] = '\0'; printf("\n$%s\t
%s$\t%s",stk,a,ac); i = i - 2;
}

30
}

for(z = 0; z < c; z++) {


if(stk[z] == 'E' && stk[z+1] == '*' && stk[z+2] == 'E') {
stk[z] = 'E';
stk[z+1] = '\0';
stk[z+2] = '\0'; printf("\n$%s\t
%s$\t%s",stk,a,ac); i = i - 2;
}
}

for(z = 0; z < c; z++) {


if(stk[z] == 'E') {
stk[z] = 'S';
stk[z+1] = '\0';
stk[z+1] = '\0'; printf("\n$%s\t
%s$\t%s",stk,a,ac); i = i - 2;
}
}

for(z = 0; z < c; z++) {


if(stk[z] == 'a') {
stk[z] = 'a';
stk[z+1] = '\0';
stk[z+1] = '\0'; printf("\n$%s\t
%s$\t%s",stk,a,ac); i = i - 2;
}
}

return 0;
}

31
Output:

Result: Thus, the C program for Shift Reduce Parsing been executed and the output has
been verified successfully.

32
Expt. No: 8
Date: 04/03/24 Computation of Leading and Trailing

Aim: To write a program for Computation of Leading and Trailing in C

Algorithm:

1. ‘a’ is in LEADING(A) is A→ γaδ where γ is ε Or any non-terminal.


2. If ‘a’ is in LEADING(B) and A→B, then ‘a’ is in LEADING(A).
3. ‘a’ is in TRAILING(A) is A→ γaδ where δ is ε Or any non-terminal.
4. If ‘a’ is in TRAILING(B) and A→B, then ‘a’ is in TRAILING(A)

Program:

#include<iostream>
#include<string>
using namespace std;

int nt, t, top = 0;


char s[50], NT[10], T[10], l[10][10], tr[50][50];

int searchnt(char a) {
for(int i = 0; i < nt; i++) {
if (NT[i] == a)
return i;
}
return -1;
}

int searchter(char a) {
for(int i = 0; i < t; i++) {
if (T[i] == a)
return i;
}
return -1;
}

33
void push(char a) {
s[top] = a; top+
+;
}

char pop() {
top--;
return s[top];
}

void installl(int a, int b) {


if (l[a][b] == 'f') {
l[a][b] = 't';
push(T[b]);
push(NT[a]);
}
}

void installt(int a, int b) {


if (tr[a][b] == 'f') {
tr[a][b] = 't';
push(T[b]);
push(NT[a]);
}
}

int main() {
int i, j, k;
char pr[30][30], b, c;

cout << "Enter the number of productions: ";


int n;
cin >> n;
cout << "Enter the productions one by one: " << endl;
for (i = 0; i < n; i++)
cin >> pr[i];

nt = 0;
t = 0;
for (i = 0; i < n; i++) {
if (searchnt(pr[i][0]) == -1)
34
NT[nt++] = pr[i][0];
}
for (i = 0; i < n; i++) {
for (j = 3; j < strlen(pr[i]); j++) {
if (searchnt(pr[i][j]) == -1) {
if (searchter(pr[i][j]) == -1)
T[t++] = pr[i][j];
}
}
}
for (i = 0; i < nt; i++) {
for (j = 0; j < t; j++)
l[i][j] = 'f';
}
for (i = 0; i < nt; i++) {
for (j = 0; j < t; j++)
tr[i][j] = 'f';
}
for (i = 0; i < nt; i++) {
for (j = 0; j < n; j++) {
if (NT[(searchnt(pr[j][0]))] == NT[i])
{ if (searchter(pr[j][3]) != -1)
installl(searchnt(pr[j][0]), searchter(pr[j][3]));
else {
for (k = 3; k < strlen(pr[j]); k++) {
if (searchnt(pr[j][k]) == -1) {
installl(searchnt(pr[j][0]), searchter(pr[j][k]));
break;
}
}
}
}} }

while (top != 0) {
b = pop();
c = pop();
for (int s = 0; s < n; s++) {
if (pr[s][3] == b)
installl(searchnt(pr[s][0]), searchter(c));
}
}
35
for (i = 0; i < nt; i++) {
cout << "Leading[" << NT[i] << "]\t{";
for (j = 0; j < t; j++) {
if (l[i][j] == 't')
cout << T[j] << ",";
}
cout << "}" << endl;
}
top = 0;
for (i = 0; i < nt; i++) {
for (j = 0; j < n; j++) {
if (NT[searchnt(pr[j][0])] == NT[i]) {
if (searchter(pr[j][strlen(pr[j]) - 1]) != -1)
installt(searchnt(pr[j][0]), searchter(pr[j][strlen(pr[j]) - 1]));
else {
for (k = (strlen(pr[j]) - 1); k >= 3; k--) {
if (searchnt(pr[j][k]) == -1) {
installt(searchnt(pr[j][0]), searchter(pr[j][k]));
break;
}
}
}
}
}
}
while (top != 0) {
b = pop();
c = pop();
for (int s = 0; s < n; s++) {
if (pr[s][3] == b)
installt(searchnt(pr[s][0]), searchter(c));
}
}
for (i = 0; i < nt; i++) {
cout << "Trailing[" << NT[i] <<

36
Output:

Result: Thus, the C program for Computation of Leading and Trailing has been executed and
the output has been verified successfully.

37
Expt. No: 9
Date: 09/03/24 Computation of LR(0) Items

Aim: To write a program for Computation of LR(0) items in C

Algorithm:

1. Start
2. Generate augmented grammar.
3. Start with C0 by including all marked productions [S->.α]
4. Compute the closure of item set C0
5. Perform a read operation on items in an item set.
6. Compute the closure of new item set.
7. Continue reading until all .S have travelled through all item sets

Program:

#include<iostream.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>

void forswitch(char, int);


void conv(int);

char arg[10][10], op[5][2], ch[10], go[3][3], c[10];

void main()
{
int i = -1, m = 0, k = 10;
clrscr();
cout << "\t\t\tTHREE ADDRESS CODE";
gotoxy(15, 7);
cout << "OPERATOR";
gotoxy(30, 7);
cout << "ARGUMENT-1";
gotoxy(45, 7);
cout << "ARGUMENT-2";

38
gotoxy(60, 7);
cout << "GOTO";
gotoxy(15, 8);
cout << "";
do
{
i++;
gotoxy(2, k);
printf("[%d]", i);
gotoxy(18, k);
scanf("%s", &op[i]);
forswitch(op[i][0], i);
gotoxy(33, k);
scanf("%s", &arg[m + i]);
gotoxy(48, k);
scanf("%s", &arg[m + 1 + i]);
gotoxy(61, k);
scanf("%s", &go[i]);
conv(m + i);
conv(m + 1 + i);
k++;
m++;
} while (i != 3);
printf("ASSEMBLY LANGUAGE CODE");
printf("\n\n100\tMOV %s,RO", arg[0]);
printf("\n101\tMOV %s,R1", arg[1]);
printf("\n102\tCMP R0,R1"); printf("\
n103\t%s 107", ch); printf("\n104\
tMOV %s,R2", arg[3]); printf("\n105\
tMOV R2,%s", arg[2]); printf("\n106\
tJUMP 109"); printf("\n107\tMOV
%s,R2", arg[5]); printf("\n108\tend");
getch();
}

void conv(int x)
{
if (isdigit(arg[x][0]))
{
strcpy(c, "#");

39
strcat(c, arg[x]);
strcpy(arg[x], c);
}
}

void forswitch(char sh, int t)


{
if (t < 1)
switch (sh)
{
case '<':
strcpy(ch, "JC");
break;
case '>':
strcpy(ch, "JNC");
break;
case '=':
strcpy(ch, "JZ");
break;
case '-':
break;
default:
gotoxy(8, 40);
cout << "\n\t\tINVALID ENTRY";
exit(0);
break;
}
}

40
Output:

Result: Thus, the C program for Computation of LR(0) items has been executed and the output
has been verified successfully.
41
Expt. No: 10
Date: 18/03/24 Intermediate Code Generation – Postfix, Prefix

Aim: To write a program for the implementation for intermediate code generation – postfix,
prefix in C.

Algorithm:
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
i. If the precedence of the scanned operator is greater than the precedence of the
operator in the stack(or the stack is empty), push it.
ii. Else, Pop the operator from the stack until the precedence of the scanned operator is
less-equal to the precedence of the operator residing on the top of the stack. Push the
scanned operator to the stack.
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop and output from the stack until an
‘(‘ is encountered.
6. Repeat steps 2-6 until infix expression is scanned.
7. Pop and output from the stack until it is not empty. Output is postfix expression.
8. Reverse the infix string.
9. Apply infix to postfix operations.
10. Reversed output string is prefix expression.

Program:

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

#define MAX_EXPR_LENGTH 100

int stack[MAX_EXPR_LENGTH];
int top = -1;

// Function to push an element onto the stack


void push(int x) {
if (top < MAX_EXPR_LENGTH - 1) {
stack[++top] = x;
} else {

42
printf("Stack Overflow\n");
exit(EXIT_FAILURE);
}
}

// Function to pop an element from the stack


int pop() {
if (top >= 0) {
return stack[top--];
} else {
printf("Stack Underflow\n");
exit(EXIT_FAILURE);
}
}

int main() {
char exp[MAX_EXPR_LENGTH];
int n1, n2, n3, num;

printf("Enter the expression :: ");


scanf("%[^\n]", exp); // Allowing spaces in the expression

char *e = exp;
while (*e != '\0') {
if (isdigit(*e)) {
// Extracting the operand from characters
num = 0;
while (isdigit(*e)) {
num = num * 10 + (*e - '0');
e++;
}
push(num);
} else if (*e != ' ') { // Skipping whitespace
n1 = pop();
n2 = pop();
switch (*e) {
case '+':
n3 = n2 + n1;
break;
case '-':
n3 = n2 - n1;
43
break;
case '*':
n3 = n2 * n1;
break;
case '/':
if (n1 != 0)
n3 = n2 / n1;
else {
printf("Division by zero error\n");
exit(EXIT_FAILURE);
}
break;
default:
printf("Invalid operator: %c\n", *e);
exit(EXIT_FAILURE);
}
push(n3);
}
e++;
}

// Print the result


if (top == 0) { // Ensure only one element (result) is left in the stack
printf("\nThe result of expression %s = %d\n\n", exp, pop());
} else {
printf("Invalid expression\n");
}
return 0;
}

44
Output:

Result: Thus, program to convert infix expression to postfix and prefix expression has been
executed.

45
Expt. No: 11
Date: 25/03/24 Intermediate Code Generator – 3 Address Code

Aim: To write a program to construct assembly language code from the input three address
code.

Algorithm:
1. Start
2. Get input for the Three Address Code.
3. Identify the addressing mode.
4. Identify the relational operator used in the statement.
5. Generate and display the assembly language code.

Program:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void pm();
void plus();
void div();
int i, ch, j, l, addr = 100;
char ex[10], exp[10], exp1[10], exp2[10], id1[5], op[5],
id2[5]; int main()
{
while(1)
{
printf("\n1. Assignment\n2. Arithmetic\n3. Relational\n4. Exit\nEnter the choice: ");
scanf("%d", &ch);
switch(ch)
{

46
case 1:
printf("\nEnter the expression with assignment operator: ");
scanf("%s", exp);
l = strlen(exp);
exp2[0] = '\0';
i = 0;
while(exp[i] != '=')
{
i++;
}
strncat(exp2, exp, i);
strrev(exp);
exp1[0] = '\0';
strncat(exp1, exp, l - (i + 1));
strrev(exp1);
printf("Three address code:\ntemp = %s\n%s = temp\n", exp1, exp2);
break;
case 2:
printf("\nEnter the expression with arithmetic operator: ");
scanf("%s", ex);
strcpy(exp, ex);
l = strlen(exp);
exp1[0] = '\0';
for(i = 0; i < l; i++)
{
if(exp[i] == '+' || exp[i] == '-')
{
if(exp[i + 2] == '/' || exp[i + 2] == '*')
47
{
pm();
break;
}
else
{
plus();
break;
}
}
else if(exp[i] == '/' || exp[i] == '*')
{
div();
break;
}
}
break;
case 3:
printf("\nEnter the expression with relational operator: ");
scanf("%s %s %s", id1, op, id2);
if(strcmp(op, "<") == 0 || strcmp(op, ">") == 0 || strcmp(op, "<=") == 0 || strcmp(op,
">=") == 0 ||
strcmp(op, "==") == 0 || strcmp(op, "!=") == 0)
{
printf("\n%d\tif %s %s %s goto %d\n", addr, id1, op, id2, addr + 3);
addr++;
printf("%d\tT := 0\n", addr);
addr++;

48
printf("%d\tgoto %d\n", addr, addr + 2);
addr++;
printf("%d\tT := 1\n", addr);
}
else
{
printf("Expression is error\n");
}
break;
case 4:
exit(0);
break;
}
}
return 0;
}
void pm()
{
strrev(exp);
j = l - i - 1;
strncat(exp1, exp, j);
strrev(exp1);
printf("Three address code:\ntemp = %s\ntemp1 = %c %c temp\n", exp1, exp[j + 1], exp[j]);
}
void div()
{
strncat(exp1, exp, i + 2);
printf("Three address code:\ntemp = %s\ntemp1 = temp %c %c\n", exp1, exp[i + 2], exp[i +
49
3]);
}

void plus()
{
strncat(exp1, exp, i + 2);
printf("Three address code:\ntemp = %s\ntemp1 = temp %c %c\n", exp1, exp[i + 2], exp[i +
3]);
}

Output:

Result: Thus, program to construct assembly code from given ICG three address code has
been executed.
50
Expt. No: 12
Date: 25/03/24 A Simple Code Generator

Aim: To write a program for a simple code generator in C.

Algorithm:

1. Start the Program


2. Open the source file and store the contents as quadruples
3. Check for operators
4. Write the generated code into output definition of the file in output C.
5. Print the output
6. Stop the program.

Program:

#include<iostream>
#include<string.h>
#include<conio.h>

using namespace std;

char reg[10][3] = {"R0", "R1", "R2", "R3", "R4", "R5"};


char stmt[10][10], code[15];
int nostmt = 0, i = 0, output[15];

void icode(char source[10], char dest[10], int out) {


strcat(code, source);
strcat(code, " ");
strcat(code, dest);
output[i] = out;
cout << code << endl;
getch();
}

int main() {
int j, i;
cout << "Enter the statements (END to end): \n";
do {
cin >> stmt[nostmt++];
} while(strcmp(stmt[nostmt-1], "END") != 0);
nostmt = nostmt - 1;
cout << "\nTHE ASSEMBLY CODE IS\n\n";

51
52
for(i = 0; i < nostmt; i++) {
strcpy(code, "");
int rd = -1, rs = -1, k;
for(j = 0; j < i; j++) {
if(stmt[j][0] == stmt[i][2])
rs = output[j];
if(stmt[j][0] == stmt[i][4])
rd = output[j];
}
if(rs == -1) {
strcpy(code, "MOV ");
char temp[2] = {stmt[i][2], '\0'};
icode(temp, reg[i], i);
}
if(stmt[i][3] == '+')
strcpy(code, "ADD ");
if(stmt[i][3] == '-')
strcpy(code, "SUB ");
if(stmt[i][3] == '*')
strcpy(code, "MUL ");
if(stmt[i][3] == '/')
strcpy(code, "DIV ");
if(rd == -1) {
char temp[2] = {stmt[i][4], '\0'};
if(rs != -1)
k = output[rs];
else
k = i;
icode(temp, reg[k], k);
}
if(rs != -1 && rd != -1) {
int flag = 0;
for(j = i; j < nostmt; j++) {
if(stmt[j][2] == stmt[i][2] || stmt[j][2] == stmt[i][4])
flag = 1;
}
if(flag != 1)
icode(reg[output[rs]], reg[output[rd]], output[rd]);
if(flag == 1)
icode(reg[output[rd]], reg[output[rs]], output[rs]);
}
}
strcpy(code, "MOV ");
char temp[2] = {stmt[i-1][0], '\0'};
icode(reg[output[i-1]], temp, 0);
return 0;
}
53
Output:

Result: Thus, the C program for A Simple Code Generator has been executed and the output has
been verified successfully.
54
Expt. No: 13
Date: 02/04/24 Implementation of DAG

Aim: To write a program to construct Directed Acyclic graph for the input expression.

Algorithm:
1. Start
2. Get the expression from the user.
3. Construct the syntax tree for the given expression.
4. Construct table for the given expression.
5. Insert into left pointer as per condition.
6. Insert into right pointer as per condition.
7. Set the label.

Program:

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>

struct da {
int ptr, left, right;
char label;
} dag[25];

void main() {
int ptr, l, j, n = 0, i = 0, x, y, k;
char store, input1[25], var;
clrscr();

for (i = 0; i < 25; i++) {


dag[i].ptr = -1;
dag[i].left = -1;
dag[i].right = -1;
dag[i].label = ' ';
}

55
printf("\n\nENTER THE EXPRESSION\n\n");
scanf("%s", input1);
l = strlen(input1);

a:
for (i = 0; input1[i] != ')'; i++);

for (j = i; input1[j] != '('; j--);


for (x = j + 1; x < i; x++) {
if (isalpha(input1[x]))
input[n++] = input1[x];
else if (input1[x] != '0')
store = input1[x];
input[n++] = store;
}
for (x = j; x <= i; x++)
input1[x] = '0';
if (input1[0] != '0')
goto a;

for (i = 0; i < n; i++) {


dag[i].label = input[i];
dag[i].ptr = i;

if (!isalpha(input[i]) && !isdigit(input[i])) {


dag[i].right = i - 1;
ptr = i;
var = input[i - 1];

if (isalpha(var))
ptr = ptr - 2;
else {
ptr = i - 1;
b:
if (!isalpha(var) && !isdigit(var)) {
ptr = dag[ptr].left;
var = input[ptr];
goto b;
} else
ptr = ptr - 1;
}
56
dag[i].left = ptr;
}
}

for (i = 0; i < n; i++) {


for (j = 0; j < n; j++) {
if ((dag[i].label == dag[j].label && dag[i].left == dag[j].left) && dag[i].right == dag[j].right) {
for (k = 0; k < n; k++) {
if (dag[k].left == dag[j].ptr)
dag[k].left = dag[i].ptr;
if (dag[k].right == dag[j].ptr)
dag[k].right = dag[i].ptr;
}
dag[j].ptr = dag[i].ptr;
}
}
}

printf("\n DAG FOR GIVEN EXPRESSION\n\n");


printf("\n\n PTR \t LEFT PTR \t RIGHT PTR \t LABEL \n\n");
for (i = 0; i < n; i++) {
printf("\n %d\t\t%d\t\t%d\t\t%c\n", dag[i].ptr, dag[i].left, dag[i].right, dag[i].label);
}
getch();
}

57
Output:

Result: Thus, the C program for Implementation of DAG has been executed and the output has
been verified successfully.

58
Expt. No: 14
Date: 10/04/24 Implementation of Global Data Flow Analysis

Aim: To implement Global Data Flow Analysis in C.

Program:

#include <stdio.h>
#include <string.h>

struct op {
char left[10];
char right[10];
} op2[15], prt[15];

int main() {
int a, j, i, k, n, m, q, l = 1;
char *p, *li;

char temp, t;
char *tem,
*mat;

printf("Enter the number of values: ");


scanf("%d", &n);

for (i = 0; i < n; i++) {


printf("Enter left value: ");
scanf("%s", op2[i].left);
printf("Enter right value: ");
scanf("%s", op2[i].right);
}

printf("Intermediate code:\n");
for (i = 0; i < n; i++) {
printf("Lineno=%d\n", l);
printf("%s=", op2[i].left);
printf("%s\n", op2[i].right);
l++;
59
}

60
printf("Dataflow analysis:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
mat = strstr(op2[j].right, op2[i].left);
if (mat) {
printf("\n%s is live at %s\n", op2[i].left, op2[j].right);
}
}
}

return 0;
}

Output:

Result: C program for global data flow analysis is implemented and executed successfully.

61
Expt. No: 15
Date: 18/04/24 Implementation of One Storage Allocation Strategy

Aim: To write a program to implement storage allocation strategy in C.

Algorithm:

1. Initially check whether the stack is empty


2. Insert an element into the stack using push operation
3. Insert more elements on to the stack until it becomes full
4. Delete an element from the stack using pop operation
5. Display the elements in the stack
6. Stop the program by exit.

Program:

#include<stdio.h>
#include<conio.h>

int i, stk[100], top=-1, n;

void show() {
if (top == -1) {
printf("Stack is empty.\n");
return;
}
printf("Stack: ");
for (i = 0; i <= top; i++)
printf("%d\t", stk[i]);
printf("\n");
}

void push() {
int item;
if (top == n-1)
printf("Stack is full.\n");
else {
printf("Enter the item: ");
scanf("%d", &item);
stk[++top] = item;
}

62
63
}

void pop() {
if (top == -1)
printf("Stack is empty.\n");
else {
printf("%d is popped.\n", stk[top]);
top--;
}
}

int main() {
int op;
printf("Enter the size of the stack: ");
scanf("%d", &n);
do {
printf("\n1 : Push");
printf("\n2 : Pop");
printf("\n3 : Display");
printf("\n4 : Exit");
printf("\nEnter your choice: ");
scanf("%d", &op);
switch (op) {
case 1:
push();
break;
case 2:
pop();
break;
case 3:
show();
break;
}
} while (op != 4);
getch();
return 0;
}

64
Output:

Result: One storage allocation strategy has been written and executed successfully in C language.

65
66

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy