75% found this document useful (8 votes)
6K views

CS6612 - Compiler Design Lab Manual

The document provides algorithms and programs for implementing various lexical and syntactic analysis tasks using tools like Lex and Yacc: 1. It presents the algorithm and program for implementing a lexical analyzer to recognize patterns in C code using Lex. The program tokenizes identifiers, keywords, operators and other tokens. 2. The algorithm and Yacc program for validating arithmetic expressions using operators like +, -, *, / is described. The program recognizes valid expressions and returns an error for invalid ones. 3. A Yacc program to recognize valid C variable names starting with a letter followed by letters or digits is implemented. 4. A calculator program implementing basic mathematical operations like addition, subtraction, multiplication, division, logarithms

Uploaded by

Anonymous lk281D
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
75% found this document useful (8 votes)
6K views

CS6612 - Compiler Design Lab Manual

The document provides algorithms and programs for implementing various lexical and syntactic analysis tasks using tools like Lex and Yacc: 1. It presents the algorithm and program for implementing a lexical analyzer to recognize patterns in C code using Lex. The program tokenizes identifiers, keywords, operators and other tokens. 2. The algorithm and Yacc program for validating arithmetic expressions using operators like +, -, *, / is described. The program recognizes valid expressions and returns an error for invalid ones. 3. A Yacc program to recognize valid C variable names starting with a letter followed by letters or digits is implemented. 4. A calculator program implementing basic mathematical operations like addition, subtraction, multiplication, division, logarithms

Uploaded by

Anonymous lk281D
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 32

1.

IMPLEMENTATION OF SYMBOL TABLE


AIM:
To write a C program to implement a symbol table.
ALGORITHM:
1) Start the program.
2) Get the input from the user with the terminating symbol $.
3) Allocate memory for the variable by dynamic memory allocation function.
4) If the next character of the symbol is an operator then only the memory is allocated.
5) While reading, the input symbol is inserted into symbol table along with its memory
address.
6) The steps are repeated till $ is reached.
7) To reach a variable, enter the variable to the searched and symbol table has been checked for
corresponding variable, the variable along with its address is displayed as result.
8) Stop the program.
PROGRAM:
#include <stdio.h>
#include<conio.h>
#include<ctype.h>
#include<alloc.h>
#include<string.h>
#include<math.h>
void main()
{
int i=0,j=0,x=0,n,flag=0;
void *p,*add[5];
char ch,srch,b[15],d[15],c;
clrscr();
printf("Expression terminated by $ : ");
while((c=getchar())!='$'){ b[i]=c;i++;}n=i-1;
printf("Given Expression : ");
i=0;
while(i<=n)
{
printf("%c",b[i]);
i++;
}
printf("\n Symbol Table\n");
printf("Symbol\taddr\ttype");
while(j<=n)
{
c=b[j];
if(isalpha(toascii(c)))
1

{
if(j==n)
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("%c\t%d\tidentifier",c,p);
}
else
{
ch=b[j+1];
if(ch=='+'||ch=='-'||ch=='*'||ch=='=')
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("\n%c\t%d\tidentifier\n",c,p);
x++;
}}}
j++;
}
printf("\nThe symbol is to be searched");
srch=getch();
for(i=0;i<=x;i++)
{
if(srch==d[i])
{
printf("\nSymbol Found");
printf("\n%c%s%d\n",srch," @address ",add[i]);
flag=1;
} }
if(flag==0)
printf("\nSymbol Not Found");
getch();
}
OUTPUT:
Expression terminated by $ : c=a+b$
Given Expression : c=a+b
Symbol Table
Symbol Addr Type
c
1900
identifier
a
2004
identifier
b
2106
identifier
The symbol is to be searched
Symbol Found
b @address 2106
RESULT:
Thus the C program for symbol table is implemented and executed successfully.
2

2. DEVELOP A LEXICAL ANALYZER TO RECOGNIZE A FEW


PATTERNS IN C
AIM:
To write and execute a C program to implement the lexical analyzer.
ALGORITHM:
1. Start the program.
2. Declare the file pointer and necessary variables.
3. Open the input file in the read mode.
4. Use the analyze function to analyze the input program and store the identifiers, keywords and
operator on idhd, keyhd, ophd respectively.
5. Stores the tokens in data structure linked lists.
6. Increment the line number of each token and its occurrences.
7. Using the show function print the linked lists in a tabular format.
8. Stop the program.
PROGRAM:
#include<string.h>
#include<ctype.h>
#include<stdio.h>
void keyword(char str[10])
{
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||
strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||
strcmp("double",str)==0||strcmp("static",str)==0||strcmp("switch",str)==0||
strcmp("case",str)==0)
printf("\n%s is a keyword",str);
else
printf("\n%s is an identifier",str);
}
main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
printf("\nEnter the c program");/*gets(st1);*/
f1=fopen("input","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
3

while((c=getc(f1))!=EOF)
{
if(isdigit(c))
{
tokenvalue=c-'0';
c=getc(f1);
while(isdigit(c))
{
tokenvalue*=10+c-'0';
c=getc(f1);
}
num[i++]=tokenvalue;
ungetc(c,f1);
}
else
if(isalpha(c))
{
putc(c,f2);
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
putc(c,f2);
c=getc(f1);
}
putc(' ',f2);
ungetc(c,f1);
}
else
if(c==' '||c=='\t')
printf(" ");
else
if(c=='\n')
lineno++;
else
putc(c,f3);
}
fclose(f2);
fclose(f3);
fclose(f1);
printf("\nThe no's in the program are");
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("The keywords and identifiersare:");
while((c=getc(f2))!=EOF)
{
if(c!=' ')
str[k++]=c;
else
4

{
str[k]='\0';
keyword(str);
k=0;
}
}
fclose(f2);
f3=fopen("specialchar","r");
printf("\nSpecial characters are");
while((c=getc(f3))!=EOF)
printf("%c",c);
printf("\n");
fclose(f3);
printf("Total no. of lines are:%d",lineno);
}
INPUT & OUTPUT:
Enter the c program
#include<stdio.h>
main()
{
int a=10,b=20,c;
c=a+b;
printf("%d",c);
}
^Z
The no's in the program are1020
The keywords and identifiersare:
include is an identifier
stdio is an identifier
h is an identifier
main is an identifier
int is a keyword
a is an identifier
b is an identifier
c is an identifier
c is an identifier
a is an identifier
b is an identifier
printf is an identifier
d is an identifier
c is an identifier
Special characters are#<.>(){=,=,;=+;("%",);}
Total no. of lines are:8
RESULT:
Thus the C program for lexical analyzer to recognize few patterns is implemented and executed
successfully.
5

3. IMPLEMENTATION OF LEXICAL ANALYZER USING LEX TOOL


AIM:
To implement the lexical analyzer using lex tool for a subset of C language.
ALGORITHM:
1.

Start the program.

2.

Declare necessary variables and creates token representation using Regular.

3.

Print the pre processor or directives, keywords by analysis of the input program.

4.

In the program check whether there are arguments.

5.

Declare a file and open it as read mode.

6. Read the file and if any taken in source program matches with RE that all returned as
integer value.
7.

Print the token identified using YYdex() function.

8.

Stop the program

PROGRAM:
%{
%}
identifier[a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
int |
float |
char |
double |
while |
do |
if |
break |
continue |
void |
switch |
return |
else |
goto {printf("\n%s is a keyword",yytext);}
{identifier}\( {printf("\n function %s",yytext);}
\{ {printf("\nblock begins");}
\} {printf("\nblock ends");}
\( {printf("\n");ECHO;}
{identifier}(\[[0-9]*\])* {printf("\n%s is an identifier",yytext);}
\".*\" {printf("\n %s is a string ",yytext);}
[0-9]+ {printf("\n%s is a number",yytext);
}
6

\<= |
\>= |
\< |
\> |
\== {printf("\n %s is a relational operator",yytext);}
\= |
\+ |
\- |
\/ |
\& |
% {printf("\n %s is a operator",yytext);}
.|
\n;
%%
int main(int argc,char **argv)
{
FILE *file;
file=fopen("inp.c","r");
if(!file)
{
printf("could not open the file!!!");
exit(0);
}
yyin=file;
yylex();
printf("\n\n");
return(0);
}
int yywrap()
{
return 1;
}

OUTPUT:
C:\Documents and Settings\admin\Desktop>flex alex.l
C:\Documents and Settings\admin\Desktop>gcc lex.yy.c
C:\Documents and Settings\admin\Desktop>a.exe
#include<stdio.h> is a preprocessor directive
void is a keyword
function main(
block begins
int is a keyword
a is an identifier
b is an identifier
c is an identifier
function printf(
"enter the value for a,b" is a string
function scanf(
"%d%d" is a string
& is a operator
a is an identifier
& is a operator
b is an identifier
c is an identifier
= is a operator
a is an identifier
+ is a operator
b is an identifier
function printf(
"the value of c:%d" is a string
& is a operator
c is an identifier
block ends

RESULT:
Thus the program to implement lexical analyzer using lex tool is executed and implemented
successfully.
8

4. GENERATE
CATEGORIES

YACC

SPECIFICATION

FOR

FEW

SYNTACTIC

A) PROGRAM TO RECOGNIZE A VALID ARITHMETIC EXPRESSION THAT USES


OPERATOR +, - , * AND /.
ALGORITHM:
1. Accept the token generated in lex part as input
2. Specify order of procedure
3. Define rules with end point
4. Parse input string from standard input by calling yyparse() by main function
5. Print the result of any rules matches
6. If none of results defined matches print invalid expression
COMPILATION STEPS:
$ lex exp.l
$ yacc d exp.y
$ cc lex.yy.c y.tab.c ll ly
$ ./a.out
PROGRAM:
Yacc<Exp.y>
%token NUMBER ID NL
%left '+' '-'
%left '*' '/'
%%
stmt : exp NL { printf(Valid Expression); exit(0);}
;
exp :
exp '+' exp
| exp '-' exp
| exp '*' exp
| exp '/' exp
| '(' exp ')'
| ID
| NUMBER
;
%%
int yyerror(char *msg)
{
printf(Invalid Expression\n);
exit(0);
}
9

main ()
{
printf(Enter the expression\n);
yyparse();
}
Lex<Exp.L>
%{
#include y.tab.h
%}
%%
[0-9]+ { return NUMBER; }
[a-zA-Z][a-zA-Z0-9_]* { return ID; }
\n { return NL ;}
. { return yytext[0]; }
%%

RESULT:
Thus the program for validating arithmetic expressions using Yacc is implemented and executed
successfully.

10

B) PROGRAM TO RECOGNIZE A VALID VARIABLE WHICH STARTS WITH


A LETTER FOLLOWED BY ANY NUMBER OF LETTERS OR DIGITS.
PROGRAM:
Yacc<Let.Y>
%token DIGIT LETTER NL UND
%%
stmt : variable NL { printf(Valid Identifiers\n); exit(0);}
;
variable : LETTER alphanumeric
;
alphanumeric: LETTER alphanumeric
| DIGIT alphanumeric
| UND alphanumeric
| LETTER
| DIGIT
| UND
;
%%
int yyerror(char *msg)
{
printf(Invalid Expression\n);
exit(0);
}
main ()
{
printf(Enter the variable name\n);
yyparse();
}
Lex<Let.L>
%{
#include y.tab.h
%}
%%
[a-zA-Z] { return LETTER ;}
[0-9] { return DIGIT ; }
[\n] { return NL ;}
[_] { return UND; }
. { return yytext[0]; }
%%

RESULT:
Thus the program is executed successfully.
11

C) IMPLEMENTATION OF CALCULATOR USING LEX AND YACC


PROGRAM:
Lex<Cal.L>
%{
#include"y.tab.h"
#include<math.h>
%}
%%
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {yylval.dval=atof(yytext);return
NUMBER;}
log |
LOG {return LOG;}
In {return nLOG;}
sin |
SIN {return SINE;}
cos |
COS {return COS;}
tan |
TAN {return TAN;}
mem {return MEM;}
[\t];
\$ return 0;
\n|. return yytext[0];
%%
Yacc<Cal.Y>
%{
double memvar;
%}
%union
{
double dval;
}
%token<dval>NUMBER
%token<dval>MEM
%token LOG SINE nLOG COS TAN
%left '-' '+'
%left '*' '/'
%right '^'
%left LOG SINE nLOG COS TAN
%nonassoc UMINUS
%type<dval>expression
%%
start:statement'\n'
|start statement'\n'
;
12

statement:MEM'='expression {memvar=$3;}
| expression{printf("Answer=%g\n",$1);}
;
expression:expression'+'expression {$$=$1+$3;}
| expression '-' expression {$$=$1-$3;}
| expression '*' expression {$$=$1*$3;}
| expression '/' expression
{
if($3==0)
yyerror("divide by zero");
else
$$=$1/$3;
}
|expression'^'expression {$$=pow($1,$3);}
;
expression:'-'expression %prec UMINUS{$$=-$2;}
|'('expression')'{$$=$2;}
|LOG expression {$$=log($2)/log(10);}
|nLOG expression {$$=log($2);}
|SINE expression {$$=sin($2*3.14/180);}
|COS expression {$$=cos($2*3.14/180);}
|TAN expression {$$=tan($2*3.14/180);}
|NUMBER {$$=$1;}
|MEM {$$=memvar;}
;
%%
main()
{
printf("Enter the expression");
yyparse();}
int yyerror(char *error)
{
printf("%s\n",error);
}
OUTPUT:
[linuxpert@fosslab ~]$ vi cal.l
[linuxpert@fosslab ~]$ lex cal.l
[linuxpert@fosslab ~]$ yacc -d cal.y
[linuxpert@fosslab ~]$ cc lex.yy.c y.tab.c -ll -lm
[linuxpert@fosslab ~]$ ./a.out
Enter the expression(5+2)*(3-1)/(2)
Answer=7

RESULT:
Thus the program to implement calculator using LEX and YACC tool is executed successfully and
output is verified.
13

5. CONVERT THE BNF RULES INTO YACC FORM AND WRITE CODE TO
GENERATE ABSTRACT SYNTAX TREE.
AIM:
To Convert the BNF rules into Yacc form and write code to generate Abstract Syntax Tree
ALGORITHM:
1. Start the program.

2.
3.
4.
5.

Include the header file.


In int code.l,declare the variable lie no as integer and assign it to be equal to 1.
Start the int code.l with declarative section.
In translation rules section define keywords ,data types and integer along with
their actions .
Start the main block. In main block check the statement

6.
7. 1.declarative 2.assignment 3.conditional 4.if and else 5.While assignment.
8. Perform the actions of that particular block.
9. In main program declare the parameters arg c as int end *argv[] as char.
10.
In main program open file in read mode.
11.
Print the output in a file.
12.
End the program.
Lex<Bnf.L>
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]*
number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN;
if return IF;
else return ELSE;
while return WHILE;
int |
char |
float return TYPE;
{identifier} {strcpy(yylval.var,yytext);
return VAR;}
{number} {strcpy(yylval.var,yytext);
return NUM;}
\< |
\> |
\>= |
14

\<= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
Yacc <Bnf.Y>
%{
#include<string.h>
#include<stdio.h>
struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack
{
int items[100];
int top;
}stk;
int Index=0,tIndex=0,StNo,Ind,tInd;
extern int LineNo;
%}
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
| CONDST
| WHILEST
15

;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{
strcpy(QUAD[Index].op,"=");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1);
strcpy($$,QUAD[Index++].result);
}
;
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR
| NUM
;
CONDST: IFST{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
};
ELSEST: ELSE{
tInd=pop();
Ind=pop();
push(tInd);
16

sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
StNo=Index-1;
}
| VAR
| NUM
;
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
WHILELOOP: WHILE '(' CONDITION ')' {
strcpy(QUAD[Index].op,"==");
strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
push(Index);
Index++;
}
;
%%
extern FILE *yyin;
int main(int argc,char *argv[])
{
FILE *fp;
int i;
if(argc>1)
{
fp=fopen(argv[1],"r");
if(!fp)
{
printf("\n File not found");
exit(0);
}
yyin=fp;
17

}
yyparse();
printf("\n\n\t\t ----------------------------\n\t\t Pos Operator Arg1 Arg2 Result\n\t\t--------------------");
for(i=0;i<Index;i++)
{
printf("\n\t\t %d\t %s\t %s\t %s\t %s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].result);
}
printf("\n\t\t -----------------------");
printf("\n\n");
return 0;
}
void push(int data)
{
stk.top++;
if(stk.top==100)
{
printf("\n Stack overflow\n");
exit(0);
}
stk.items[stk.top]=data;
}
int pop()
{
int data;
if(stk.top==-1)
{
printf("\n Stack underflow\n");
exit(0);
}
data=stk.items[stk.top--];
return data;
}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[Index].op,op);
strcpy(QUAD[Index].arg1,arg1);
strcpy(QUAD[Index].arg2,arg2);
sprintf(QUAD[Index].result,"t%d",tIndex++);
strcpy(result,QUAD[Index++].result);
}
yyerror()
{
printf("\n Error on line no:%d",LineNo);
}
Input<Vi Test .C>
main()
{
int a,b,c;
if(a<b)
{a=a+b;}
18

while(a<b)
{a=a+b;}
if(a<=b)
{c=a-b;}
else
{c=a+b;}
}
OUTPUT:
[linuxpert@fosslab ~]$ vi bnf.y
[linuxpert@fosslab ~]$ yacc -d bnf.y
[linuxpert@fosslab ~]$ gcc lex.yy.c y.tab.c -ll -lm
[linuxpert@fosslab ~]$ ./a.out test.c
---------------------------------------------------------------------------Pos Operator
Arg1
Arg2
Result
----------------------------------------------------------------------------0
<
a
b
t0
1

==

t0

t1

FALSE

GOTO

5
t1

<

==

t2

FALSE

10

t3

t3

GOTO

10

<=

11

==

t4

12

13

t5

14

GOTO

15

16

t6

t2

5
b
FALSE

t4
15
t5

17

19

t6

----------------------------------------------------------------------------RESULT:
Thus the program to convert the BNF rules into Yacc form is implemented and executed
successfully.

8. IMPLEMENT ANY ONE STORAGE ALLOCATION STRATEGIES (HEAP,


STACK, STATIC)
AIM:
To Implement any one storage allocation strategies (Heap,Stack,Static)
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Heap
{
int data;
struct Heap *next;
}node;
node *create();
void main()
{
/*local declarations*/
int choice,val;
char ans;
node *head;
void display(node *);
node *search(node *,int);
node *insert(node *);
void dele(node **);
head=NULL;
do
{
clrscr();
printf("\n Program to perform various operations on heapusing dynamic memory management");
printf("\n1.Create");
printf("\n2.Display");
printf("\n3.Insert an element in a list");
printf("\n4.Delete an element from list");
printf("\n5.Quit");
printf("\n Enter Your Choice(1-5)");
scanf("%d",&choice);
switch(choice)
{
case 1:head=create();
break;
case 2:display(head);
20

break;
case 3:head=insert(head);
break;
case 4:dele(&head);
break;
case 5:exit(0);
default:clrscr();
printf("Invalid Choice,Try again");
getch();
}
}while(choice!=5);
}
node *create()
{
node *temp,*new1,*head;
int val,flag;
char ans='y';
node *get_node();
temp=NULL;
flag=TRUE;
/*flag to indicate whether a new node is created for the first time or not*/
do
{
printf("\n Enter the Element");
scanf("%d",&val);
/*allocate new node*/
new1=get_node();
if(new1==NULL)
printf("\n Memory is not allocated");
new1-> data=val;
if (flag==TRUE)/* Executed only for the first time*/
{
head=new1;
temp=head; /*head is the first node in the heap*/
flag=FALSE;
}
else
{
/*temp keeps track of the most recently created node*/
temp->next=new1;
temp=new1;
}
printf("\nDo you want to enter more elements?(y/n)");
ans=getch();
}while(ans=='y');
printf("\nThe list is created");
getch();
clrscr();
return head;
}
node *get_node()
21

{
node *temp;
temp=(node*)malloc(sizeof(node));
//using the mem. Allocation function
temp->next=NULL;
return temp;
}
void display(node*head)
{
node *temp;
temp=head;
if(temp==NULL)
{
printf("\n The list is empty\n");
getch();
clrscr();
return;
}
while(temp!= NULL)
{
printf("%d->",temp-> data);
temp=temp->next;
}
printf("NULL");
getch();
clrscr();
}
node *search(node *head,int key)
{
node *temp;
int found;
temp=head;
if (temp==NULL)
{
printf("The linked list is empty\n");
getch();
clrscr();
return NULL;
}
found=FALSE;
while((temp!=NULL)&&(found==FALSE))
{
if(temp->data != key)
temp = temp->next;
else
found = TRUE;
}
if(found == TRUE)
{
printf("\n The Elements is present in the list\n");
getch();
22

return temp;
}
else
printf("\n The Element is not present in the list\n");
getch();
return NULL;
}
node *insert(node *head)
{
int choice;
node *insert_head(node*);
void insert_after(node*);
void insert_last(node*);
printf("\nInsert a node as a head node");
printf("\nInsert a node as a last node");
printf("\nInsert a node as at the intermediate position in the list ");
printf("\nEnter your choice for insertion of node ");
scanf("%d",&choice);
switch(choice)
{
case 1:head = insert_head(head);
break;
case 2:insert_last(head);
break;
case 3:insert_after (head);
break;
}
return head;
}
/*Insertion of node at first position*/
node *insert_head(node*head)
{
node *New,*temp;
New = get_node();
printf ("\n Enter the element which you want to insert ");
scanf("%d",&New->data);
if(head == NULL)
head = New;
else
{
temp=head;
New->next = temp;
head= New;
}
return head;
}
/*Insertion of node at last position*/
void insert_last(node *head)
{
node *New,*temp;
New = get_node();
23

printf ("\n Enter the element which you want to insert ");
scanf("%d",&New->data);
if(head == NULL)
{
head = New;
}
else
{
temp=head;
while(temp->next!=NULL)
temp=temp->next;
temp->next=New;
New->next=NULL;
}
}
/*Insertion of node at intermediate position*/
void insert_after(node *head)
{
int key;
node *New,*temp;
New = get_node();
printf("Enter the element after which you want to insert ");
scanf("%d",&key);
temp=head;
do
{
if(temp->data==key)
{
printf ("Enter element which you want to insert ");
scanf("%d",&New->data);
New->next=temp->next;
temp->next=New;
return;
}
else
temp=temp->next;
}while(temp!=NULL);
}
node *get_prev(node *head,int val)
{
node *temp,*prev;
int flag;
temp = head;
if(temp == NULL)
return NULL;
flag = FALSE;
prev = NULL;
while(temp!=NULL && !flag)
{
if(temp->data!=val)
{
24

prev = temp;
temp = temp->next;
}
else
flag = TRUE;
}
if(flag) /*if Flag is true*/
return prev;
else
return NULL;
}
void dele(node **head)
{
int key;
node *New,*temp, *prev;
temp=*head;
if (temp== NULL)
{
printf ("\n The list is empty\n ");
getch();
clrscr();
return;
}
clrscr();
printf("\nENTER the Element you want to delete:");
scanf("%d",&key);
temp= search(*head,key);
if(temp !=NULL)
{
prev = get_prev(*head,key);
if(prev != NULL)
{
prev ->next = temp-> next;
free(temp);
}
else
{
*head = temp->next;
free(temp); // using the mem. Dellocation function
}
printf("\nThe Element is deleted\n");
getch();
clrscr();
}
}

25

OUTPUT:
Program to perform various operations on heap using Dynamic memory management.
1.Create
2.Display
3.Insert an element in a list
4. Delete an element from list
5. Quit
Enter your choice(1-5) 1
Enter the element: 10
Do you want to enter more elements? (y/n) y
Enter the element:20
Do you want to enter more elements?(y/n)y
Enter the element:30
Do you want to enter more elements?(y/n)n
The List is created
Program to perform various operations on Heap using Dynamic memory management.
1. Create
2. Display
3. Insert an element in a list
4. Delete an element from list
5. Quit
Enter your choice(1-5) 4
Enter the element you want to delete: 20
The element is present in the list
The element is deleted
Program to perform various operations on Heap using Dynamic memory management.
1. Create
2. Display
3. Insert an element in a list
4. Delete an element from list
5. Quit
Enter your choice(1-5) 2
10-> 30-> NULL

RESULT:
Thus the program to implement storage allocation for HEAP is implemented and executed
successfully.

26

10. IMPLEMENT THE BACK END OF THE COMPILER WHICH TAKES THE
THREE ADDRESS CODE AND PRODUCES THE 8086 ASSEMBLY LANGUAGE
INSTRUCTIONS THAT CAN BE ASSEMBLED AND RUN USING A 8086
ASSEMBLER. THE TARGET ASSEMBLY INSTRUCTIONS CAN BE SIMPLE MOVE,
ADD, SUB, JUMP. ALSO SIMPLE ADDRESSING MODES ARE USED.
OR
IMPLEMENTATION OF CODE GENERATOR
AIM:
To write a C program to implement Simple Code Generator.
ALGORITHM:
1.
2.
3.
4.
5.
6.
7.
8.
9.

Start
Get address code sequence.
Determine current location of 3 using address (for 1st operand).
If current location not already exist generate move (B,O).
Update address of A(for 2nd operand).
If current value of B and () is null,exist.
If they generate operator () A,3 ADPR.
Store the move instruction in memory
Stop

PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<graphics.h>
typedef struct
{
char var[10];
int alive;
}
regist;
regist preg[10];
void substring(char exp[],int st,int end)
{
int i,j=0;
char dup[10]="";
for(i=st;i<end;i++)
dup[j++]=exp[i];
dup[j]='0';
strcpy(exp,dup);
}
int getregister(char var[])
{
int i;
for(i=0;i<10;i++)
{
27

if(preg[i].alive==0)
{
strcpy(preg[i].var,var);
break;
}
}
return(i);
}
void getvar(char exp[],char v[])
{
int i,j=0;
char var[10]="";
for(i=0;exp[i]!='\0';i++)
if(isalpha(exp[i]))
var[j++]=exp[i];
else
break;
strcpy(v,var);
}
void main()
{
char basic[10][10],var[10][10],fstr[10],op;
int i,j,k,reg,vc,flag=0;
clrscr();
printf("\nEnter the Three Address Code:\n");
for(i=0;;i++)
{
gets(basic[i]);
if(strcmp(basic[i],"exit")==0)
break;
}
printf("\nThe Equivalent Assembly Code is:\n");
for(j=0;j<i;j++)
{
getvar(basic[j],var[vc++]);
strcpy(fstr,var[vc-1]);
substring(basic[j],strlen(var[vc-1])+1,strlen(basic[j]));
getvar(basic[j],var[vc++]);
reg=getregister(var[vc-1]);
if(preg[reg].alive==0)
{
printf("\nMov R%d,%s",reg,var[vc-1]);
preg[reg].alive=1;
}
op=basic[j][strlen(var[vc-1])];
substring(basic[j],strlen(var[vc-1])+1,strlen(basic[j]));
getvar(basic[j],var[vc++]);
switch(op)
{
case '+': printf("\nAdd"); break;
case '-': printf("\nSub"); break;
28

case '*': printf("\nMul"); break;


case '/': printf("\nDiv"); break;
}
flag=1;
for(k=0;k<=reg;k++)
{
if(strcmp(preg[k].var,var[vc-1])==0)
{
printf("R%d, R%d",k,reg);
preg[k].alive=0;
flag=0;
break;
}
}
if(flag)
{
printf(" %s,R%d",var[vc-1],reg);
printf("\nMov %s,R%d",fstr,reg);
}
strcpy(preg[reg].var,var[vc-3]);
getch();
}
}

INPUT & OUTPUT:


Enter the Three Address Code:
a=b+c
c=a*c
exit
The Equivalent Assembly Code is:
Mov R0,b
Add c,R0
Mov a,R0
Mov R1,a
Mul c,R1
Mov c,R1

RESULT:
Thus the program to implement simple code generator is executed successfully and the output is
verified.
29

11. IMPLEMENTATION OF SIMPLE CODE OPTIMIZATION TECHNIQUES


AIM:
To write a C program to implement Code Optimization Techniques.
ALGORITHM:
Input: Set of L values with corresponding R values.
Output: Intermediate code & Optimized code after eliminating common expressions.
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct op
{
char l;
char r[20];
}
op[10],pr[10];
void main()
{
int a,i,k,j,n,z=0,m,q;
char *p,*l;
char temp,t;
char *tem;
clrscr();
printf("Enter the Number of Values:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
op[i].l=getche();
printf("\tright: ");
scanf("%s",op[i].r);
}
printf("Intermediate Code\n") ;
for(i=0;i<n;i++)
{
printf("%c=",op[i].l);
printf("%s\n",op[i].r);
}
for(i=0;i<n-1;i++)
{
temp=op[i].l;
for(j=0;j<n;j++)
{
p=strchr(op[j].r,temp);
if(p)
30

{
pr[z].l=op[i].l;
strcpy(pr[z].r,op[i].r);
z++; }}}
pr[z].l=op[n-1].l;
strcpy(pr[z].r,op[n-1].r);
z++;
printf("nAfter Dead Code Eliminationn");
for(k=0;k<z;k++) {
printf("%ct=",pr[k].l);
printf("%sn",pr[k].r);
}
for(m=0;m<z;m++) {
tem=pr[m].r;
for(j=m+1;j<z;j++) {
p=strstr(tem,pr[j].r);
if(p) {
t=pr[j].l;
pr[j].l=pr[m].l;
for(i=0;i<z;i++) {
l=strchr(pr[i].r,t) ;
if(l) {
a=l-pr[i].r;
printf("pos: %d",a);
pr[i].r[a]=pr[m].l; }}}}}
printf("Eliminate Common Expression\n");
for(i=0;i<z;i++)
{
printf("%c\t=",pr[i].l);
printf("%s\n",pr[i].r);
}
for(i=0;i<z;i++)
{
for(j=i+1;j<z;j++)
{
q=strcmp(pr[i].r,pr[j].r);
if((pr[i].l==pr[j].l)&&!q)
{
pr[i].l='\0';
strcpy(pr[i].r,'\0');
}
}
}
printf("Optimized Code\n");
for(i=0;i<z;i++)
{
if(pr[i].l!='\0')
{
printf("%c=",pr[i].l);
printf("%s\n",pr[i].r);
}
31

}
getch();
}
INPUT & OUTPUT:
Enter the Number of Values:5
left: a right: 9
left: b right: c+d
left: e right: c+d
left: f right: b+e
left: r right: f
Intermediate Code
a=9
b=c+d
e=c+d
f=b+e
r=f
nAfter Dead Code Eliminationnbt=c+dnet=c+dnft=b+enrt=fnpos: 2Eliminate Common Ex
pression
b
=c+d
b
=c+d
f
=b+b
r
=f
Optimized Code
b=c+d
f=b+b
r=f

RESULT:
Thus the program for code optimization is implemented and executed successfully, and the
output is verified.
32

You might also like