Ex-9 To 14
Ex-9 To 14
Aim:
Algorithm:
1. Start.
2. Make the first line instruction, instruction with labels, branch instructions as individual nodes.
3. Print the individual blocks along with the line numbers.
4. Construct the control flow graph.
5. Print the blocks, graph and the exit block for the given code.
6. Stop.
Source Code:
cfa.l:
%option noyywrap
%{
#include<stdio.h>
#include<string.h>
struct graph{
char code[500];
}blarr[1000];
%}
space [ \t]
rop ">"|"<"|"=="|"<="|">="|"<>"
aop "+"|"-"|"*"|"/"|"%"
asignop "="
digit [0-9]
num {digit}+
letter [a-zA-Z]
iden {letter}({letter}|{digit})*
Input:
cfain.txt:
a=1
b=2
L0: c = a + b
Sample Output:
Block No:1 Line no's:1,2,
Block No:2 Line no's:3,4,5,
Block No:3 Line no's:6,7,
Block No:4 Line no's:8,9,10,
Block No:5 Line no's:11,12,13,
Block No:6 Line no's:14,15,16,
Result:
Thus the program for control flow analysis has been compiled and executed successfully.
AIM:
To write a C program to implement data flow analysis.
ALGORITHM:
1. START.
2. Get the number of statements and the statements.
3. For the first read statement tokenize definition and expression, store the expression value in
SOURCE CODE:
#include<stdio.h>
#include<string.h>
struct block
{
char l[5];
char r[20];
}b[10];
struct result
{
char res[10];
}r[10];
printf("\nCode :: \n");
for(i=0;i<n-1;i++)
{
printf("\t%s = ",b[i].l);
printf("%s\n",b[i].r);
}
printf("\treturn %s",b[i].r);
//split
r[n-1].res[0] = b[i].r[0];
for(i=n-2;i>=0;i--)
{
k=0;
len = strlen(b[i].r);
for(j=0;j<len;j+=2)
{
if(check(b[i].r[j], i))
{
r[i].res[k++] = b[i].r[j];
r[i].res[k++] = ',';
}
}
//k = j;
len = strlen(r[i+1].res);
for(j=0;j<len;j+=2)
{
if(b[i].l[0] != r[i+1].res[j])
{
if(check(r[i+1].res[j], i))
{
r[i].res[k++] = r[i+1].res[j];
r[i].res[k++] = ',';
}
}
}
Enter no of values :: 6
Left :: a
Right :: 7
Left :: b
Right :: a+a
Left :: c
Right :: b+a
Left :: d
Right :: a+b
Left :: e
Right :: d+c
Left :: return
Right :: e
Code:
a=1
b = a+a
c = b+a
d = a+b
e = d+c
return e
a=1 --
b = a+a a
c = b+a b,a
d = a+b a,b,c
e = d+c d,c
return e e
RESULT:
Thus a program to implement data flow analysis have been written and executed successfully.
DATE:
AIM:
ALGORITHM:
Push Operation
The process of putting a new data element onto stack is known as a Push Operation. Push operation involves a
series of steps
Pop operation
p by 1.
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;
int isempty() {
if(top == -1)
return 1;
else
return 0;
}
int isfull() {
if(top == MAXSIZE)
return 1;
else
return 0;
}
int peek() {
return stack[top];
}
int pop() {
int data;
if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
} else {
printf("Could not retrieve data, Stack is empty.\n");
}
}
int push(int data) {
if(!isfull()) {
top = top + 1;
stack[top] = data;
} else {
printf("Could not insert data, Stack is full.\n");
}
}
int main() {
/ push items on to the stack push(3);
push(5);
printf("Elements: \n");
return 0;
}
Elements:
15
12
RESULT:
Thus the given program for storage allocation strategy has been compiled and executed successfully.
Aim:
To implement directed acyclic graph using LEX and YACC.
Algorithm:
Lex.l:
1. Start.
4. In the rule section create the Regular expression along their actions to tokenize the string from the
program file.
5. Stop
Yacc.y:
1. Start.
2. Include the header file and also the tokens that are returned by the LEX and also give precedence to
the operators.
3. In the rule section write a grammar to find the index, left and right nodes of the current node in the
expression.
4. Then print the DAG as a table with index, right and left nodes with the current node.
8. Stop
Source Code:
dag.l
%option noyywrap
%{
#include "y.tab.h"
dag.y
%{
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
struct DAG
{
char *sym;
int left,right;
}table[100];
char subexp[20][20];
int sub_exp_tbl_idx[20];
int tbl_entry=0,idx,sub_exp_count=0;
int search(char *);
int issubexp(char *);
int search_subexp(char *);
void add_subexp(char *);
%}
%union{char *name;}
%token <name> num id
%type <name> e start
%left '+' '-'
%left '*' '/'
%right '='
%%
start : id '=' e {
idx = search($1);
if(idx == -1)
addsym($1,45,45);
if(issubexp($3))
Sample Output:
Enter an expr:(a+b)*(a+b)
Enter an expr:(a+b)*(a-b)
0 a - -
1 b - -
2 + 0 1
3 - 0 1
4 * 2 3
Result:
Thus the program for directed acyclic graph has been compiled and executed successfully.
DATE:
AIM:
ALGORITHM:
Lex.l:
1. Start.
2. Add the option noyywrap and yylval as extern variable in the definition section.
3. Include the header files in the definition section.
4. In the rule section create the Regular expression along their actions to tokenize the string from the
program file.
5. Stop
Yacc.y:
1. Start.
2. Include the header file and also the tokens that are returned by the LEX and also give precedence to
the operators.
3. In the rule section write a grammar to generate the assembly code.
4. Call yyparse() to get more tokens from the LEX.
5. Define a yyerror() function to display a error message if the token is invalid.
6. Also have swapreg() to add symbols and inc_timer() and other required functions.
7. Stop.
codegen.l:
%option noyywrap
%{
#include "y.tab.h"
extern YYSTYPE yylval;
%}
%%
[a-z][a-z]* {yylval.str=strdup(yytext);return id;}
[1-9][0-9]* {yylval.str=strdup(yytext);return num;}
[ \t]* {}
[=+-/*\n] {return *yytext;}
. {}
%%
codegen.y:
%{
#include<stdio.h>
#include<string.h>
char* getreg(char *);
void clr(char *);
void mk_instr(char*, char*, char*);
char *code;
enum reg {AX,BX,CX,DX};
char regname[4][3]={"AX","BX","CX","DX"};
char regcont[4][100] = {"$","$","$","$"};
char * swapreg_content(char*);
int regcont_timer[4]={0,0,0,0};
int yylex();
extern FILE *yyin;
%}
%union {char *str;}
%left '+' '-'
%left '*' '/'
%right '='
%type <str> e start line
%token <str> id num
%%
start : line '\n' {printf("\n");inc_timer();}
| start line '\n' {printf("\n");inc_timer();}
SAMPLE INPUT:
intrcode.txt :
a=b+c
x=2
a=a*x
d = b *10
y = d/c
y = e -5
SAMPLE OUTPUT:
MOV AX,b
MOV BX,c
ADD AX,BX
MOV a,AX
MOV x,2H
MOV AX,a
MOV CX,x
MUL AX,CX
MOV AX,b
MUL AX,10H
MOV d,AX
MOV AX,d
DIV AX,BX
MOV y,AX
MOV AX,e
SUB AX,5H
MOV y,AX
RESULT:
Thus the program for intermediate code generation has been compiled and executed successfully.
AIM:-
To write a C program to implement the code generation algorithm.
ALGORITHM:-
1. Start.
2. Invoke a function getreg to determine the location L where the result of the computation y op z should be stored. L
will usually be a register, but it could also be a memory location. We shall describe getreg shortly.
3. Consult the address descriptor for y to determine y, (one of) the current location(s) of y. Prefer the register for y if the
value of y is currently both in memory and a register. If the value of y is not already in l, generate the instruction MOV
y, L to place a copy of y in L.
4. Generate the instruction op z, L where z is a current location of z. Again, prefer a register to a memory location if z is
in both. Update the address descriptor of x to indicate that x is in location L. If L is a register, update its descriptor to
indicate that it contains the value of x, and remove x from all other register descriptors.
5. If the current values of y and/or z have no next users, are not live on exit from the block, and are in register descriptor
to indicate that, after execution of x:=y op z, those registers no longer will contain y and/or z, respectively.
6. Stop.
PROGRAM:-
#include<stdio.h>
#include<string.h>
struct op
{
char l[5];
char r[20];
}op[10], pr[10];
void main()
{
int n, i, j, k=0, m, a, b;
char temp[10], t[10], *p, *q;
printf("Enter no of values :: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nLeft :: ");
scanf("%s",op[i].l);
printf("Right :: ");
scanf("%s",op[i].r);
}
for(i=0;i<n-1;i++)
{
strcpy(temp, op[i].l);
for(j=0;j<n;j++)
{
p = strstr(op[j].r, temp);
if(p)
{
strcpy(pr[k].l, op[i].l);
strcpy(pr[k].r, op[i].r);
k++;
}
}
}
strcpy(pr[k].l, op[n-1].l);
strcpy(pr[k].r, op[n-1].r);
k++;
for(i=0;i<k;i++)
{
strcpy(temp,pr[i].r);
for(j=i+1;j<k;j++)
{
p = strstr(temp, pr[j].r);
if(p)
{
strcpy(t, pr[j].l);
strcpy(pr[j].l, pr[i].l);
for(m=0;m<k;m++)
{
q = strstr(pr[m].r,t);
if(q)
{
a = q-pr[m].r;
pr[m].r[a] = pr[i].l[0];
OUTPUT :
Enter no of values :: 5
Left :: a
Right :: 7
Left :: b
Left :: e
Right :: c+d
Left :: f
Right :: b+e
Left :: r
Right :: f
Intermediate Code ::
a=7
b = c+d
e = c+d
f = b+e
r=f
Optimized code ::
b = c+d
f = b+b
r=f
RESULT :
Thus the program for code optimization is executed successfully and implemented.