Compiler Lab Manual
Compiler Lab Manual
LAB MANUAL
COMPILER DESIGN
(18CSC304J)
SEMESTER- VI
Year/Sem
Prepared By
: III year/VI
Approved By
(HOD/CSE)
`
SYLLABUS:
L T P C
COMPILER DESIGN LAB
PURPOSE
To Practice and Implement the System Software tools and Compiler design Techniques
INSTRUCTIONAL OBJECTIVES
LIST OF EXPERIMENTS
ALGORITHM:
Step1: Start the program.
Step2: Declare all the variables and file pointers.
Step3: Display the input program.
Step4: Separate the keyword in the program and display it.
Step5: Display the header files of the input program
Step6: Separate the operators of the input program and display it.
Step7: Print the punctuation marks.
Step8: Print the constant that are present in input program.
Step9: Print the identifiers of the input program
Program
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int main(){
char ch, buffer[15], operators[] = "+-*/%=";
FILE *fp;
inti,j=0;
fp = fopen("program.txt","r");
if(fp == NULL){
printf("error while opening the file\n");
exit(0);
}
while((ch = fgetc(fp)) != EOF){
for(i = 0; i< 6; ++i){
if(ch == operators[i])
printf("%c is operator\n", ch);
}
if(isalnum(ch)){
buffer[j++] = ch;
}
else if((ch == ' ' || ch == '\n') && (j != 0)){
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
printf("%s is keyw88ord\n", buffer);
else
printf("%s is indentifier\n", buffer);
}
}
fclose(fp);
return 0;
}
Output
RESULT:
Thus the C program to Implementation of Lexical Analyzer A has been executed and the
output has been verified successfully
2. CONVERSION OF REGULAR EXPRESSION TO NFA
AIM:
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<conio.h>
void main()
{
char m[20],t[10][10];
intn,i,j,r=0,c=0;
clrscr();
printf("\n\t\t\t\tSIMULATION OF NFA");
printf("\n\t\t\t\t*****************");
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
t[i][j]=' ';
}
}
printf("\n\nEnter a regular expression:");
scanf("%s",m);
n=strlen(m);
for(i=0;i<n;i++)
{
switch(m[i])
{
case '|' : {
t[r][r+1]='E';
t[r+1][r+2]=m[i-1];
t[r+2][r+5]='E';
t[r][r+3]='E';
t[r+4][r+5]='E';
t[r+3][r+4]=m[i+1];
r=r+5;
break;
}
case '*':{
t[r-1][r]='E';
t[r][r+1]='E';
t[r][r+3]='E';
t[r+1][r+2]=m[i-1];
t[r+2][r+1]='E';
t[r+2][r+3]='E';
r=r+3;
break;
}
case '+': {
t[r][r+1]=m[i-1];
t[r+1][r]='E';
r=r+1;
break;
}
default:
{
if(c==0)
{
if((isalpha(m[i]))&&(isalpha(m[i+1])))
{
t[r][r+1]=m[i];
t[r+1][r+2]=m[i+1];
r=r+2;
c=1;
}
c=1;
}
else if(c==1)
{
if(isalpha(m[i+1]))
{
t[r][r+1]=m[i+1];
r=r+1;
c=2;
}
}
else
{
if(isalpha(m[i+1]))
{
t[r][r+1]=m[i+1];
r=r+1;
c=3;
}
}
}
break;
}
}
printf("\n");
for(j=0;j<=r;j++)
printf(" %d",j);
printf("\n___________________________________\n");
printf("\n");
for(i=0;i<=r;i++)
{
for(j=0;j<=r;j++)
{
printf(" %c",t[i][j]);
}
printf(" | %d",i);
printf("\n");
}
printf("\nStart state: 0\nFinal state: %d",i-1);
getch();
}
OUTPUT:
Enter a regular Expression: a|b
SIMULATION OF NFA
*****************
0 1 2 3 4 5
___________________________________
E E |0
a |1
E |2
b |3
E |4
|5
Start state: 0
Final state: 5
RESULT:
Thus the C program to convert regular expression to NFA has been executed and the
output has been verified successfully.
3. CONVERSION OF DFA TO NFA
AIM:
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<string.h>
#include<math.h>
int ninputs;
int dfa[100][2][100] = {0};
int state[10000] = {0};
char ch[10], str[1000];
int go[10000][2] = {0};
int arr[10000] = {0};
int main()
{
int st, fin, in;
int f[10];
int i,j=3,s=0,final=0,flag=0,curr1,curr2,k,l;
int c;
printf("\nFollow the one based indexing\n");
for(i=0;i<st;i++)
state[(int)(pow(2,i))] = 1;
int p,q,r,rel;
in = pow(2,in);
i=0;
go[(int)(pow(2,i))][j] = stf;
printf("%d-%d-->%d\n",(int)(pow(2,i)),j,stf);
if(state[stf]==0)
arr[x++] = stf;
state[stf] = 1;
}
if(new==0)
new =
go[h][j];
new = new |
(go[h][j]);
}
}
if(state[new]==0)
{
arr[x++] = new;
state[new] = 1;
}
}
}
printf("STATE 0 1\n");
for(i=0;i<10000;i++)
{
if(state[i]==1)
{
//printf("%d**",i);
int y=0;
if(i==0)
printf("q0 ");
else
for(j=0;j<st;j++)
{
int x = 1<<j;
if(x&i)
{
printf("q%d ",j);
y = y+pow(2,j);
//printf("y=%d ",y);
}
}
//printf("%d",y);
printf(" %d %d",go[y][0],go[y][1]);
printf("\n");
}
}
j=3;
while(j--)
{
printf("\nEnter string");
scanf("%s",str);
l = strlen(str);
curr1 = in;
flag = 0;
printf("\nString takes the following path-->\n");
printf("%d-",curr1);
for(i=0;i<l;i++)
{
curr1 = go[curr1][str[i]-'0'];
printf("%d-",curr1);
}
for(i=0;i<fin;i++)
{
if(curr1 & (1<<f[i]))
{
flag = 1;
break;
}
}
if(flag)
printf("\nString Accepted");
else
printf("\nString Rejected");
return 0;
}
OUTPUT:
Follow the one based indexing
Enter the number of states::3
Give state numbers from 0 to 2
Enter number of final states 1
Enter final states::4
Enter the number of rules according to NFA::4
Define transition rule as "initial state input symbol final state"
101
111
102
204
Enter initial state::1
Solving according to DFA1-0-->0
1-1-->0
2-0-->6
2-1-->2
4-0-->0
4-1-->0
for 0 ---- for 0 ----
The total number of distinct states are::
STATE 0 1
q0 0 0
q0 0 0
q1 6 2
q2 0 0
q1 q2 0 0
Enter stringabbb
String takes the following path-->
2-0-0-0-0-
Final state - 0
String Rejected
Enter stringabba
String takes the following path-->
2-0-0-0-0-
Final state - 0
String Rejected
Enter string b
String Accepted
RESULT:
Thus, the C program to convert NFA to DFA has been executed and the output has
been verified successfully.x
4. ELIMINATION OF AMBIGUITY, LEFT RECURSION AND
LEFT FACTORING
AIM:
To study the ambiguity, perform Left recursion and Left factoring.
1.Eliminating Ambiguity
Rule-01:
Rule-02:
Problem-01:
Solution-
To convert the given grammar into its corresponding unambiguous grammar, we implement the
precedence and associativity constraints.
We have-
● Given grammar consists of the following operators-
+,.,*
● Given grammar consists of the following operands-
a,b
Using the precedence and associativity rules, we write the corresponding unambiguous grammar
as-
E→E+T/T
T→T.F/F
F → F* / G
G→a/b
Unambiguous Grammar
OR
E→E+T/T
T→T.F/F
F → F* / a / b
Unambiguous Grammar
2. Left Recursion
● Left Recursion. The production is left-recursive if the leftmost symbol on the right side
is the same as the non-terminal on the left side.
● For example, expr → expr + term. If one were to code this production in a recursive-
descent parser, the parser would go in an infinite loop.
Left recursion is eliminated by converting the grammar into a right recursive grammar.
Then, we can eliminate left recursion by replacing the pair of productions with-
A → βA’
A’ → αA’ / ∈
(Right Recursive Grammar)
3.Left Factoring
Left factoring is another useful grammar transformation used in parsing
Left Factoring is a grammar transformation technique. It consists in "factoring out" prefixes
which are common to two or more productions.
For example, going from:
A -> α β | α γ
to:
A -> α A'
A' -> β | γ
Left factor:
Let the given grammar: A-->ab1 | ab2 | ab3
1)We can see that, for every production, there is a common prefix & if we choose any production
here, it is not confirmed that we will not need to backtrack. 2)It is non deterministic, because we
cannot choice any production and be assured that we will reach at our desired string by making
the correct parse tree. But if we rewrite the grammar in a way that is deterministic and also leaves
us to be flexible enough to make it any string that may be possible without backtracking.... it will
be:
● A --> aA', A' --> b1 | b2| b3 now if we are asked to make the parse tree for string ab2.... we
don't need back tracking. Because we can always choose the correct production when we
get A' thus we will generate the correct parse tree.
● Left factoring is required to eliminate non-determinism of a grammar. Suppose a grammar,
S -> abS | aSb
● Here, S is deriving the same terminal a in the production rule (two alternative choices for
S), which follows non-determinism. We can rewrite the production to defer the decision of
S as-
S -> aS'
S' -> bS | Sb
Thus, S' can be replaced for bS or Sb
PROGRAM:
#include<stdio.h>
#include<string.h>
void main()
{
char input[100], l[50],r[50],temp[10],tempprod[20],productions[25][50]; int
i=0,j=0,flag=0,consumed=0;
printf(“Enter the Productions:”);
scanf(“ %ls->%s”, l, r);
printf(“ %s”, r);
while(sscanf(r+consumed, “ % [^l] s”, temp) == 1 &&consumed<=strlen(r))
{
if(temp[0] == l[0])
{
flag = 1;
sprintf(productions[i++], “%s->%s%s ‘\0”, l,temp+1,1);
}
else
sprintf(productions[i++], “%s->%s%s ‘\0”,l, temp,1);
consumed += strlen(temp)+1;
}
if(flag==1)
{
sprintf(productions[i++], “%s->€ \0”, 1);
printf(“the productions after eliminating left recursion are:\n”);
for(j=0;j<i;j++)
printf(“%s \n “, productions[j]);
}
else
printf(“ The Given Grammar has no Left Recursion”);
}
OUTPUT:
Enter the Productions: E-E+T
The productions after eliminating Left Recursion are:E->+TE’ E->
Enter the Productions:
T->T*F
The productions after eliminating Left Recursion are: T-> *FT’ T->
Enter the Productions:
F->id
The Given Grammar has no Left Recursion
#include<stdio.h>
#include<conio.h>
#include<string.h>
char input[100];
int i,l;
int main()
{
printf("recursive decent parsing for the grammar");
printf("\n E->TEP|\nEP->+TEP|@|\nT->FTP|\nTP->*FTP|@|\nF-
>(E)|ID\n");
printf("enter the string to check:");
scanf("%s",input);
if(E()){
if(input[i]=='$')
printf("\n string is accepted\n"); else
printf("\n string is not accepted\n");
}
}
E(){
if(T()){
if(EP())
return(1);
else
return(0);
}
else
return(0);
}
EP(){
if(input[i]=='+'){
i++;
if(T()){
if(EP())
return(1); else return(0);
}
else
return(1);
}
}
T(){
if(F()){
if(TP())
return(1);
else
return(0);
}
else
return(0);
printf("String is not accpeted\n");
}
TP(){
if(input[i]=='*'){
i++;
if(F()){
if(TP())
return(1);
else
return(0);
}
else
return(0);
printf("The string is not accepted\n");
}
else
return(1);
}
F(){
if(input[i]=='('){
i++;
if(E()){
if(input[i]==')'){
i++;
return(1);
}
else
{
return(0);
printf("String is not accepted\n");
}
}
else
return(0);
}
else if(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')
{
i++;
return(1);
}
else
return(0);
}
OUTPUT:
$ cc rdp.c
$ ./a.out
recursive decent parsing for the grammar E-
>TEP|
EP->+TEP|@|
T->FTP|
TP->*FTP|@|
F->(E)|ID
enter the string to check:(i+i)*i string is accepted
RESULT:
Thus, the process Elimination of Ambiguity,Left Recursion & Left Factoring have been
studied.
5. FIRST AND FOLLOW COMPUTATION
AIM:
To calculate the first and Follow of the given expression
ALGORITHM:
1. Start the program
2. In the production the first terminal on R.H.S becomes the first of it
3. If the first character is non-terminal then its first is taken else Follow of left is taken
4. To find Follow find where all the non terminals appear. the first of its Follows is its
Follow
5. If the Follow is t then the Follow of left is taken
6. Finally print first and its Follow
7. Stop the program
SOURCE CODE:_
#include<stdio.h>
#include<ctype.h>
#include<string.h>
void followfirst(char, int, int);
void follow(char c);
void findfirst(char, int, int);
int count, n = 0;
char calc_first[10][100];
char calc_follow[10][100];
int m = 0;
char production[10][10];
char f[10], first[10];
int k;
char ck;
int e;
int main(int argc, char **argv)
{
int jm = 0;
int km = 0;
int i, choice;
char c, ch;
count = 8;
strcpy(production[0], "E=TR");
strcpy(production[1], "R=+TR");
strcpy(production[2], "R=#");
strcpy(production[3], "T=FY");
strcpy(production[4], "Y=*FY");
strcpy(production[5], "Y=#");
strcpy(production[6], "F=(E)");
strcpy(production[7], "F=i");
int kay;
char done[count];
int ptr = -1;
if (xxx == 1)
continue;
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;
if (first[i] == calc_first[point1][lark])
{
chk = 1;
break;
}
}
if(chk == 0)
{
printf("%c, ", first[i]);
calc_first[point1][point2++] = first[i];
}
}
printf("}\n");
jm = n;
point1++;
}
printf("\n");
printf("-----------------------------------------------\n\n");
char donee[count];
ptr = -1;
if(production[0][0] == c) {
f[m++] = '$';
}
for(i = 0; i < 10; i++)
{
for(j = 2;j < 10; j++)
{
if(production[i][j] == c)
{
if(production[i][j+1] != '\0')
{
followfirst(production[i][j+1], i, (j+2));
}
OUTPUT:
Enter the no. of production:5
E->TE’
E’->+TE’/e
T->FT’
T’->*FT’/e
F->(E) /id
First
First(E)={(,id}
First(E’)={+,e}
First(T)={(,id}-
First(T’)={*,e}
First(F)={(,id}
Follow
Follow(E)={),$}
Follow(E’)={),+,$}
Follow(T)={),+,$}
Follow(T’)={*,+,),$}
Follow(F)={*,+,),$}
RESULT:
Thus the above computation of FIRST &FOLLOW program is successfully executed.
AIM:
To write a C program for the implementation of predictive parsing table
ALGORITHM:
int count,n=0;
char calc_first[10][100];
char calc_follow[10][100];
int m=0;
char production[10][10], first[10];
char f[10];
int k;
char ck;
int e;
void follow(char c)
{
int i ,j;
if(production[0][0]==c){
f[m++]='$';
}
for(i=0;i<10;i++)
{
for(j=2;j<10;j++)
{
if(production[i][j]==c)
{
if(production[i][j+1]!='\0'){
followfirst(production[i][j+1],i,(j+2));
}
if(production[i][j+1]=='\0'&&c!=production[i][0]){
follow(production[i][0]);
}
}
}
}
}
RESULT:
Thus the Predictive Parser program is executed successfully.
AIM:
To write a program for implementing Shift Reduce Parsing using C.
ALGORITHM:
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];
void check();
int main()
{
puts("GRAMMAR is E->E+E \n E->E*E \n E->(E) \n E->id");
puts("enter input string ");
gets(a);
c=strlen(a);
strcpy(act,"SHIFT->");
puts("stack \t input \t action");
for(k=0,i=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();
}
}
}
void 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;
}
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+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
for(z=0; z<c; z++)
if(stk[z]=='(' && stk[z+1]=='E' && stk[z+2]==')')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
}
OUTPUT :
GRAMMAR is E->E+E
E->E*E
E->(E)
E->id enter input string
id+id*id+id
ALGORITHM:
1. Start the program.
2. Include the required header files and start the declaration of main method.
3. Declare the required variable and define the function for pushing and poping the
characters.
4. The operators are displayed in coliumn and row wise and stored it in a queue.
5. Using a switch case find the values of the operators.
6. Display the precedence of the operator and generate the code for precedence of operator
for the given expression.
7. Compile and execute the program for the output.
8. Stop the program
PROGRAM
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void main()
{
char grm[20][20], c;
while (c != '\0') {
flag = 1;
else {
flag = 0;
f();
}
if (c == '$') {
flag = 0;
f();
}
c = grm[i][++j];
}
}
if (flag == 1)
printf("Operator grammar");
}
Input :3
A=A*A
B=AA
A=$
Input :2
A=A/A
B=A+A
RESULT:
Thus the C program implementation for operator precedence is executed and verified.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
void isproduct(char,char);
int ister(char);
int isnter(char);
int isstate(char);
void error();
void isreduce(char,char);
char row[6][5];
};
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","emp","acc"},
{"emp","rc","sh","emp","rc","rc"},
{"emp","re","re","emp","re","re"},
{"sf","emp","emp","se","emp","emp"},
{"emp","rg","rg","emp","rg","rg"},
{"sf","emp","emp","se","emp","emp"},
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","sl","emp"},
{"emp","rb","sh","emp","rb","rb"},
{"emp","rb","rd","emp","rd","rd"},
{"emp","rf","rf","emp","rf","rf"}
};
struct gotol
char r[3][4];
};
{"emp","emp","emp"},
{"emp","emp","emp"},
{"emp","emp","emp"},
{"i","c","d"},
{"emp","emp","emp"},
{"emp","j","d"},
{"emp","emp","k"},
{"emp","emp","emp"},
{"emp","emp","emp"},
};
char ter[6]={'i','+','*',')','(','$'};
char nter[3]={'E','T','F'};
char states[12]={'a','b','c','d','e','f','g','h','m','j','k','l'};
char stack[100];
int top=-1;
char temp[10];
struct grammar
{
char left;
char right[5];
};
{'E',"T"},
{'T',"T*F"},
{'T',"F"},
{'F',"(E)"},
{'F',"i"},
};
void main()
char inp[80],x,p,dl[80],y,bl='a';
int i=0,j,k,l,n,m,c,len;
scanf("%s",inp);
len=strlen(inp);
inp[len]='$';
inp[len+1]='\0';
push(stack,&top,bl);
printt(stack,&top,inp,i);
do
x=inp[i];
p=stacktop(stack);
isproduct(x,p);
if(strcmp(temp,"emp")==0)
error();
if(strcmp(temp,"acc")==0)
break;
else
if(temp[0]=='s')
push(stack,&top,inp[i]);
push(stack,&top,temp[1]);
i++;
}
else
if(temp[0]=='r')
j=isstate(temp[1]);
strcpy(temp,rl[j-2].right);
dl[0]=rl[j-2].left;
dl[1]='\0';
n=strlen(temp);
for(k=0;k<2*n;k++)
pop(stack,&top);
for(m=0;dl[m]!='\0';m++)
push(stack,&top,dl[m]);
l=top;
y=stack[l-1];
isreduce(y,dl[0]);
for(m=0;temp[m]!='\0';m++)
push(stack,&top,temp[m]);
printt(stack,&top,inp,i);
}while(inp[i]!='\0');
if(strcmp(temp,"acc")==0)
else
getch();
if(*sp==100)
else
{
*sp=*sp+1;
s[*sp]=item;
char i;
i=s[top];
return i;
int k,l;
k=ister(x);
l=isstate(p);
strcpy(temp,A[l-1].row[k-1]);
int ister(char x)
int i;
for(i=0;i<6;i++)
if(x==ter[i])
return i+1;
return 0;
int isnter(char x)
int i;
uh uh
for(i=0;i<3;i++)
if(x==nter[i])
return i+1;
return 0;
int isstate(char p)
int i;
for(i=0;i<12;i++)
if(p==states[i])
return i+1;
return 0;
void error()
exit(0);
}
void isreduce(char x,char p)
int k,l;
k=isstate(x);
l=isnter(p);
strcpy(temp,G[k-1].r[l-1]);
char item;
if(*sp==-1)
else
item=s[*sp];
*sp=*sp-1;
return item;
int r;
printf("\n");
for(r=0;r<=*p;r++)
rep(t,r);
printf("\t\t\t");
for(r=i;inp[r]!='\0';r++)
printf("%c",inp[r]);
char c;
c=t[r];
switch(c)
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
default :printf("%c",t[r]);
break;
stack input
0 i*i+i*i$
0i5 *i+i*i$
0F3 *i+i*i$
0T2 *i+i*i$
0T2*7 i+i*i$
0T2*7i5 +i*i$
0T2*7F10 +i*i$
0E1 +i*i$
0E1+6 i*i$
0E1+6i5 *i$
0E1+6F3 *i$
0E1+6T9 *i$
0E1+6T9*7 i$
0E1 +i*i$
0E1+6 i*i$
0E1+6i5 *i$
0E1+6F3 *i$
0E1+6T9 *i$
0E1+6T9*7 i$
0E1+6T9*7i5 $
0E1+6T9*7F10 $
0E1+6T9 $
0E1 $
accept the input
RESULT:
Thus the LR(0) Program was executed and verified Successfully.
AIM:
INTRODUCTION:
● The code optimization is required to produce an efficient target code. These are two
important issues that used to be considered while applying the techniques for code
optimization.
● They are:
● The semantics equivalences of the source program must not be changed.
● The improvement over the program efficiency must be achieved without changing
the algorithm.
ALGORITHM:
1. Start the program
2. Include all the header files
3. Check for postfix expression and construct the in order DAG representation
4. Print the output
5. Stop the program
t = a + b
0
t = t + c
1 0
d = t + t 0 1
[t = a + b]
0
[t = t + c]
1 0
[d = t + t ]
0 1
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MIN_PER_RANK 1
#define MAX_PER_RANK 5
#define MIN_RANKS 3
#define MAX_RANKS 5
#define PERCENT 30
void main()
{
int i,j,k,nodes=0;
srand(time(NULL));
int ranks=MIN_RANKS+(rand()%(MAX_RANKS-MIN_RANKS+1));
printf("DIRECTED ACYCLIC GRAPH\n");
for(i=1;i<ranks;i++)
{
int new_nodes=MIN_PER_RANK+(rand()%(MAX_PER_RANK-
MIN_PER_RANK+1));
for(j=0;j<nodes;j++)
for(k=0;k<new_nodes;k++)
if((rand()%100)<PERCENT)
printf("%d->%d;\n",j,k+nodes);
nodes+=new_nodes;
}
}
OUTPUT:
DIRECTED ACYCLIC GRAPH
0-
>6;
1-
>5;
1-
>8;
2-
>5;
2-
>7;
4-
>5;
4-
>7;
ALGORITHM:
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
1 If the precedence of the scanned operator is greater than the precedence of the
operator in the stack(or the stack is empty or the stack contains a ‘(‘ ), push it.
2 Else, Pop all the operators from the stack which are greater than or equal to in precedence
than that of the scanned operator. After doing that Push the scanned operator to the stack. (If you
encounter parenthesis while popping then stop there and push the scanned operator in the stack.)
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop the stack and output it until a ‘(‘ is encountered, and
discard both the parenthesis.
6. Repeat steps 2-6 until infix expression is scanned.
7. Print the output
8. Pop and output from the stack until it is not empty.
PROGRAM:
#include<stdio.h>
int stack[20];
int top = -1;
void push(int x)
{
stack[++top] = x;
}
int pop()
{
return stack[top--];
}
int main()
{
char exp[20];
char *e;
int n1,n2,n3,num;
printf("Enter the expression :: ");
scanf("%s",exp);
e = exp;
while(*e != '\0')
{
if(isdigit(*e))
{
num = *e - 48;
push(num);
}
else
{
n1 = pop();
n2 = pop();
switch(*e)
{
case '+':
{
n3 = n1 + n2;
break;
}
case '-':
{
n3 = n2 - n1;
break;
}
case '*':
{
n3 = n1 * n2;
break;
}
case '/':
{
n3 = n2 / n1;
break;
}
}
push(n3);
}
e++;
}
printf("\nThe result of expression %s = %d\n\n",exp,pop());
return 0;
}
OUTPUT:
Enter the expression :: 245+*
The result of expression 245+* = 18
RESULT:
Thus, the C Program to Implement POSTFIX Notation in Intermediate Code Generation was
executed successfully.
\12. Implementation of Intermediate Code Generation
AIM:
To write a C program to implementation of code generation
ALGORITHM:
step 1: Start.
Step 2: Enter the three address codes.
Step 3: If the code constitutes only memory operands they are moved to
the register and according to the operation the corresponding
assembly code is generated.
Step 4: If the code constitutes immediate operands then the code will have
a # symbol proceeding the number in code.
Step 5: If the operand or three address code involve pointers then the code
generated will constitute pointer register. This content may be
stored to other location or vice versa.
Step 6: Appropriate functions and other relevant display statements are
executed.
Step 7: Stop.
SOURCE CODE
#include"stdio.h"
#include"conio.h"
#include"string.h"
#include"stdlib.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()
{
OUTPUT:
INTERMEDIATE CODE GENERATION
x=Z+c/d
Y := Z+c
x=Y/d
x := d
RESULT: Thus the Implementation of ICG as Generation of Three Address was executed
and verified Successfully.
ALGORITHM:
1. Start the program
2. Open the source file and store the contents as quadruples.
3. Check for operators, in quadruples, if it is an arithmetic operator generator it or if
assignment operator generates it, else perform unary minus on register C.
4. Write the generated code into output definition of the file in outp.c
5. Print the output.
6. Stop the program.
SOURCE CODE:
#include<stdio.h>
#include<stdio.h>
//#include<conio.h>
#include<string.h>
void main()
{
char icode[10][30],str[20],opr[10];
int i=0;
//clrscr();
printf("\n Enter the set of intermediate code (terminated by exit):\n");
do
{
scanf("%s",icode[i]);
} while(strcmp(icode[i++],"exit")!=0);
printf("\n target code generation");
printf("\n************************");
i=0;
do
{
strcpy(str,icode[i]);
switch(str[3])
{
case '+':
strcpy(opr,"ADD");
break;
case '-':
strcpy(opr,"SUB");
break;
case '*':
strcpy(opr,"MUL");
break;
case '/':
strcpy(opr,"DIV");
break;
}
printf("\n\tMov %c,R%d",str[2],i);
printf("\n\t%s%c,R%d",opr,str[4],i);
printf("\n\tMov R%d,%c",i,str[0]);
}while(strcmp(icode[++i],"exit")!=0);
//getch();
}
OUTPUT:
t=a+b
x=t
exit
Mov a,R0
ADDb,R0
Mov R0,t
Mov t,R1
ADDb,R1
Mov R1,x
RESULT:
Thus the program to implement the code generation has been successfully executed.
PROGRAM CODE:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void input();
void output();
void constant();
void expression();
struct expr
char op[2],op1[5],op2[5],res[5];
int flag;
}arr[10];
int n;
int main()
int ch=0;
input();
constant();
expression();
output();
void input()
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",arr[i].op);
scanf("%s",arr[i].op1);
scanf("%s",arr[i].op2);
scanf("%s",arr[i].res);
arr[i].flag=0;
void constant()
int i;
int op1,op2,res;
char op,res1[5];
for(i=0;i<n;i++)
op1=atoi(arr[i].op1);
op2=atoi(arr[i].op2);
op=arr[i].op[0];
switch(op)
case '+':
res=op1+op2;
break;
case '-':
res=op1-op2;
break;
case '*':
res=op1*op2;
break;
case '/':
res=op1/op2;
break;
sprintf(res1,"%d",res);
arr[i].flag=1;
change(i,i,res1);
void expression()
int i,j;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
if(strcmp(arr[i].op,arr[j].op)==0)
if(strcmp(arr[i].op,"+")==0||strcmp(arr[i].op,"*")==0)
if(strcmp(arr[i].op1,arr[j].op1)==0&&strcmp(arr[i].op2,arr[j].op2)==0 ||
strcmp(arr[i].op1,arr[j].op2)==0&&strcmp(arr[i].op2,arr[j].op1)==0)
arr[j].flag=1;
change(i,j,NULL);
else
if(strcmp(arr[i].op1,arr[j].op1)==0&&strcmp(arr[i].op2,arr[j].op2)==0)
arr[j].flag=1;
change(i,j,NULL);
} }
} }
} }
void output()
int i=0;
printf("\nOptimized code is : ");
for(i=0;i<n;i++)
if(!arr[i].flag)
printf("\n%s %s %s %s\n",arr[i].op,arr[i].op1,arr[i].op2,arr[i].res);
int i;
for(i=q+1;i<n;i++)
if(strcmp(arr[q].res,arr[i].op1)==0)
if(res == NULL)
strcpy(arr[i].op1,arr[p].res);
else
strcpy(arr[i].op1,res);
else if(strcmp(arr[q].res,arr[i].op2)==0)
if(res == NULL)
strcpy(arr[i].op2,arr[p].res);
else
strcpy(arr[i].op2,res);
OUTPUT
RESULT:
Thus the program to implement dataflow and control flow analysis has been successfully
executed.
15. IMPLEMENTATION OF ONE STORAGE
ALLOCATION STRATEGY(STACK)
AIM:
To write a program to Implement storage allocation strategy (Stack) in C.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define size 5
struct stack
int s[size];
int top;
} st;
int stfull()
return 1;
else
return 0;
st.top++;
st.s[st.top] = item;
int stempty()
if (st.top == -1)
return 1;
else
return 0;
int pop()
int item;
item = st.s[st.top];
st.top--;
return (item);
void display()
{
int i;
if (stempty())
printf("\nStack Is Empty!");
else
printf("\n%d", st.s[i]);
int main()
char ans;
st.top = -1;
printf("\n\tImplementation Of Stack");
do {
printf("\nMain Menu");
scanf("%d", &choice);
switch (choice)
{
case 1:
scanf("%d", &item);
if (stfull())
printf("\nStack is Full!");
else
push(item);
break;
case 2:
if (stempty())
else
item = pop();
break;
case 3:
display();
break;
case 4:
goto halt;
}
printf("\nDo You want To Continue?");
ans = getche();
halt:
return 0;
OUTPUT:
Implementation Of Stack
Main Menu
1.Push
2.Pop
3.Display
4.exit
Main Menu
1.Push
2.Pop
3.Display
4.exit
Enter Your Choice 1
Main Menu
1.Push
2.Pop
3.Display
4.exit
Main Menu
1.Push
2.Pop
3.Display
4.exit
Main Menu
1.Push
2.Pop
3.Display
4.exit
Main Menu
1.Push
2.Pop
3.Display
4.exit
20
10
RESULT:
Thus, the C program for Implementation of DAG has been executed and the output has
been verified successfully.