CS6612 Compiler Record
CS6612 Compiler Record
NO: 1
DATE:
AIM:
INTRODUCTION:
Name : a string
Attribute:
1. Reserved word
2. Variable name
3. Type Name
4. Procedure name
5. Constant name
Data type
Storage allocation
SYMBOL TABLE
ALGORITHM:
1. Start the Program.
2. Get the input from the user with the terminating symbol ‘$’.
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.
7. To reach a variable, enter the variable to the searched and symbol table has been
checked for corresponding variable, the variable along its address is displayed as
result.
8. Stop the program.
PROGRAM: ( IMPLEMENTATION OF SYMBOL TABLE)
# include <stdio.h>
# include <conio.h>
# include <alloc.h>
# include <string.h>
# define null 0
int size=0;
void insert();
void del();
int search(char lab[]);
void modify();
void display();
struct symbtab
{
char label[10];
int addr;
struct symtab *next;
};
struct symbtab *first,*last;
void main()
{
int op;
int y;
char la[10];
clrscr();
do
{
printf("\nSYMBOL TABLE IMPLEMENTATION\n");
printf("1. INSERT\n");
printf("2. DISPLAY\n");
printf("3. DELETE\n");
printf("4. SEARCH\n");
printf("5. MODIFY\n");
printf("6. END\n");
printf("Enter your option : ");
scanf("%d",&op);
switch(op)
{
case 1: insert();
display();
break;
case 2: display();
break;
case 3:del();
display();
break;
case 4: printf("Enter the label to be searched : ");
scanf("%s",la);
y=search(la);
if(y==1)
{ printf("The label is already in the symbol Table");
}
else
{ printf("The label is not found in the symbol table");
}
break;
case 5: modify();
display();
break;
case 6:
break;
}
}
while(op<6);
getch();
}
void insert()
{
int n;
char l[10];
printf("Enter the label : ");
scanf("%s",l);
n=search(l);
if(n==1)
{ printf("The label already exists. Duplicate cant be inserted\n");
}
else
{ struct symbtab *p;
p=malloc(sizeof(struct symbtab));
strcpy(p->label,l);
printf("Enter the address : ");
scanf("%d",&p->addr);
p->next=null;
if(size==0)
{ first=p;
last=p;
}
else
{ last->next=p;
last=p;
}
size++;
}}
void display()
{ int i;
struct symbtab *p;
p=first;
printf("LABEL\tADDRESS\n");
for(i=0;i<size;i++)
{ printf("%s\t%d\n",p->label,p->addr);
p=p->next;
}}
void modify()
{
char l[10],nl[10];
int add, choice, i, s;
struct symbtab *p;
p=first;
printf("What do you want to modify?\n");
printf("1. Only the label\n");
printf("2. Only the address of a particular label\n");
printf("3. Both the label and address\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("Enter the old label\n");
scanf("%s",l);
printf("Enter the new label\n");
scanf("%s",nl);
s=search(l);
if(s==0)
{ printf("NO such label"); }
else
{ for(i=0;i<size;i++)
{ if(strcmp(p->label,l)==0)
{ strcpy(p->label,nl); }
p=p->next;
}}
break;
case 2: printf("Enter the label whose address is to modified\n");
scanf("%s",l);
printf("Enter the new address\n");
scanf("%d",&add);
s=search(l);
if(s==0)
{ printf("NO such label");
}
else
{ for(i=0;i<size;i++)
{ if(strcmp(p->label,l)==0)
{ p->addr=add; }
p=p->next;
}}
break;
case 3: printf("Enter the old label : ");
scanf("%s",l);
printf("Enter the new label : ");
scanf("%s",nl);
printf("Enter the new address : ");
scanf("%d",&add);
s=search(l);
if(s==0)
{ printf("NO such label");
}
else
{ for(i=0;i<size;i++)
{
if(strcmp(p->label,l)==0)
{ strcpy(p->label,nl);
p->addr=add;
}
p=p->next;
}}
break;
}}
void del()
{
int a;
char l[10];
struct symbtab *p,*q;
p=first;
printf("Enter the label to be deleted\n");
scanf("%s",l);
a=search(l);
if(a==0)
{ printf("Label not found\n");
}
else
{ if(strcmp(first->label,l)==0)
{ first=first->next;
}
else if(strcmp(last->label,l)==0)
{ q=p->next;
while(strcmp(q->label,l)!=0)
{ p=p->next;
q=q->next;
}
p->next=null;
last=p;
}
else
{ q=p->next;
while(strcmp(q->label,l)!=0)
{ p=p->next;
q=q->next;
}
p->next=q->next;
}
size--;
}}
OUTPUT:
RESULT:
Thus the C program to implement the symbol table was executed and the output is verified .
EX. NO:2
DATE:
A FEW PATTERNS IN C
AIM:
INTRODUCTION:
for the Purpose of parsing. A category of token is what in linguistics might be called a part-
of-speech. Examples of token categories may include “identifier” and “integer literal”,
although the set of Token differ in different programming languages.
The process of forming tokens from an input stream of characters is called tokenization.
Sum=3 + 2;
Sum “identifier”
=
“assignment operator”
3 integer literal
+ addition operator
2 integer literal
ALGORITHM:
#include<stdio.h>
#include<conio.h>
void main()
{
int i=0,j=0,k,l,t;
char expr1[190],expr[40][10],num[10];
char keyword[12][10] = {"if", "else", "then", "while", "do", "for", "int", "float", "char",
"long","douoble"};
clrscr();
fflush(stdin);
printf("\nEnter the expression:");
gets(expr1);
while(1)
{ k = 0;
t = expr1[i];
while( (t>96 && t<123) || (t>64 && t<91) || (t>47 && t<58) )
{ expr[j][k] = expr1[i];
i++;
k++;
t = expr1[i];
if(!( (t>96 && t<123) || (t>64 && t<91) || (t>47 && t<58) ))
expr[j++][k] = NULL;
} k=0;
if(t == 42 || t == 43 || t == 45 || t == 47 || t == 61)
{ expr[j][k] = expr1[i];
expr[j++][1] = NULL;
}
if(t == 59)
break;
else if(j > 80 || t == 0)
{ printf("\nStatement Missing.");
exit(0);
getch();
getch();
} i++;
t = expr1[i];
} i = j;
printf("\n\nTotal No. of tokens: %d",j);
printf("\nSigns: ");
for(j=0;j<i;j++)
if(!strcmp(expr[j],"+") || !strcmp(expr[j],"-") || !strcmp(expr[j],"*") || !strcmp(expr[j],"/") ||
!strcmp(expr[j],";"))
{ printf("%s\t",expr[j]);
for(l=j;l<i;l++)
sprintf(expr[l],"%s",expr[l+1]);
i--;
}
printf("\nAssignment operator: ");
for(j=0;j<i;j++)
if(!strcmp(expr[j],"="))
{
printf("%s\t",expr[j]);
for(l=j;l<i;l++)
sprintf(expr[l],"%s",expr[l+1]);
i--;
}
printf("\nNumbers: ");
for(j=0;j<i;j++)
for(k=0;k<32767;k++)
{
sprintf(num,"%d",k);
if(!strcmp(expr[j],num))
{
printf("%d\t",k);
for(l=j;l<i;l++)
sprintf(expr[l],"%s",expr[l+1]);
j--;
i--;
} }
printf("\nKeywords: ");
for(j=0;j<i;j++)
for(k=0;k<11;k++)
if(!strcmp(expr[j],keyword[k]))
{
printf("%s\t",expr[j]);
for(l=j;l<i;l++)
sprintf(expr[l],"%s",expr[l+1]);
i--;
}
printf("\nIdentifiers: ");
for(j=0;j<i;j++)
printf("%s\t",expr[j]);
getch();
}
OUTPUT:
RESULT:
Thus the above program for developing the lexical the lexical analyzer and recognizing the
few pattern s in C is executed successfully and the output is verified.
EX.NO:3
DATE:
AIM:
INTRODUCTION:
THEORY:
There is a wide range of tools for construction of lexical analyzer. The majority
of these tools are based on regular expressions.
LEX:
The lex is used in the manner depicted. A specification of the lexical analyzer is
preferred by creating a program lex.1 in the lex language.
Then lex.1 is run through the lex compiler to produce a ‘c’ program lex.yy.c.
3. Declaration %%
4. Translation rules %%
5. Auxiliary procedure.
7. Definitions.
9. P1{action}
10. P2{action}
11. …..
12. …..
13. Pn{action}
15. Compile the lex program with lex compiler to produce output file as lex.yy.c.
18. Compile that file with C compiler and verify the output.
PROGRAM: (LEXICAL ANALYZER USING LEX TOOL)
lex.l
digits[0-9]
letters[a-zA-Z]
delimiters[\,\:\;]
relational[\==\!=\<\>\<=\>=]
arithmetic[\+\-\*\/\%]
%{
int line=0;
%}
%%
#.* {printf("\n%s is a preprocessor directive",yytext);}
"/*".*"*/" {printf("\n%s is a comment statement",yytext);}
\".*\" {printf("\n%s is a control string",yytext);}
int|float|char|double|while|for|do|if|break|continue|void|switch|case|long|struct|const|typedef|return|
else|return|goto {printf("\n%s is a keyword",yytext);}
{letters}({letters}|{digits})* {printf("\n %s is a identifier",yytext);}
{digits}+ {printf("\n %s is a number",yytext);}
{delimiters}? {printf("\n %s is a special symbol - delimiters",yytext);}
\{ {printf("\n %s is a opening brace",yytext);}
\} {printf("\n %s is a closing brace",yytext);}
\( {printf("\n %s is a left paranthesis",yytext);}
\) {printf("\n %s is a right paranthesis",yytext);}
{arithmetic}? {printf("\n %s is an arithmetic operators",yytext);}
{relational}? {printf("\n %s is a relational operators",yytext);}
\n {line++;}
%%
test.c
main()
{
int a,b,c;
if(a<b)
{
a=a+b;
}
else
{
c=a+b;
}
}
OUTPUT:
main is a identifier
( is a left paranthesis
) is a right paranthesis
{ is a opening brace
int is a keyword
a is a identifier
, is a special symbol - delimiters
b is a identifier
, is a special symbol - delimiters
c is a identifier
; is a special symbol - delimiters
RESULT:
Thus the program for the exercise on lexical analysis using lex has been successfully executed
and output is verified.
EX.NO:4
DATE:
GENERATE YACC SPECIFICATION FOR A FEW SYNTACTIC
CATEGORIES.
AIM :
INTRODUCTION :
ALGORITHM :
4a. Program to recognize a valid arithmetic expression that uses operator +, - , * and /.
prog4.y
%{ #include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
%}
%token num let
%left '+' '-'
%left '*' '/'
%%
Stmt : Stmt '\n' { printf ("\n.. Valid Expression.. \n"); exit(0); }
| expr
| error '\n' { printf ("\n..Invalid ..\n"); exit(0); }
;
expr : num
| let
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| '(' expr ')'
;
%%
main ( )
{printf ("Enter an expression to validate : ");
yyparse ( );}
yylex()
{
int ch;
while ( ( ch = getchar() ) == ' ' );
if ( isdigit(ch) )
return num; // return token num
if ( isalpha(ch) )
return let; // return token let
return ch; }
OUTPUT:
. Valid Expression..
C:\GnuWin32\bin> a.exe
syntax error
..Invalid .
Ex.No: 4 a Yacc program to Evaluate an arithmetic expression for operators (+,-,*, / )
eval.y
yylex ( )
{
char ch;
while ( (ch = getchar() ) == ' ' ) ;
if ( isdigit(ch) | ch == '.' )
{
ungetc ( ch, stdin );
scanf ( "%lf", &yylval );
return num;
}
return ch;
}
OUTPUT:
C:\GnuWin32\bin>gcc y.tab.c
C:\GnuWin32\bin>a.exe
4+8
Value is 12.000000
Ex: No : 4b Yacc program to recognize a valid variable, which starts with a letter followed by
any number of digits and letters.
pro.y
%{ #include <stdio.h>
#include <ctype.h>
%}
%token let dig
%%
TERM : XTERM '\n' { printf ( "\nAccepted\n" ); exit(0); }
| error { yyerror ("Rejected\n" ); }
;
XTERM : XTERM let
| XTERM dig
| let
;
%%
yylex()
{
char ch;
while ( ( ch = getchar ( ) ) == ' ' ) ;
if ( isalpha (ch) )
return let;
if ( isdigit (ch) )
return dig;
return ch;
}
main()
{
printf ("Enter a variable : ");
yyparse ();
}
yyerror(char *s)
{
printf ("%s", s);
}
OUTPUT:
C:\GnuWin32\bin>gcc y.tab.c
C:\GnuWin32\bin>a.exe
C:\GnuWin32\bin>a.exe
Accepted
EX. NO: 4 C Implementation of Calculator using LEX and YACC
cal.l
%{
#include<stdio.h>
#include<math.h>
#include "y.tab.h"
%}
%%
[0-9]+ {
yylval.dval=atoi(yytext);
return NUMBER;
}
[t];
n return 0;
. {return yytext[0];}
%%
void yyerror(char *str)
{
printf("\n Invalid Character");
}
int main()
{
printf("Enter Expression => ");
yyparse();
return(0);
}
int yywrap()
{
return 0;
}
cal.y
%{
#include<stdio.h>
int yylex(void);
%}
%union
{
float dval;
}
%token <dval> NUMBER
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
%type <dval> exp
%%
state : exp {printf("Answer = %f",$1);}
;
exp : NUMBER
| exp '+' exp {$$=$1+$3;}
| exp '-' exp {$$=$1-$3;}
| exp '*' exp {$$=$1*$3;}
| exp '/' exp {$$=$1/$3;}
| '('exp')' {$$=$2;}
| '-' exp %prec UMINUS {$$=-$2;}
;
%%
OUTPUT:
C:\GnuWin32\bin>flex cal.l
c:\GnuWin32\bin>a.exe
Answer = 11.000000
RESULT:
Thus the program for the exercise on the syntax using YACC has been executed successfully and
Output is verified.
EX.NO:5
DATE:
CONVERT THE BNF RULES INTO YACC FORM AND WRITE CODE TO
GENERATE ABSTRACT SYNTAX TREE USING AND YACC.
AIM:
INTRODUCTION:
BNF-Backus Naur form is formal notationfor encoding grammars intended for human
ALGORITHM:
3. Token digit
Line:exp”\n”{print”\n%d\n”,$1)}
Expr:expr”+”term($$=$1=$3}
Term:term”+”factor($$=$1*$3}
Factor
Factor”enter”),{$$=$2)
%%
%{
#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;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
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;
void Addquadruple(char op[5],char arg1[10],char arg2[10],char result[10]);
void puss(int data);
int pop();
%}
%union
{
char var[10];
}
CONDST: IFST{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
BLOCK {
strcpy(QUAD[Index].op,"GOTO");
strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");
puss(Index);
Index++;
};
ELSEST: ELSE{
tInd=pop();
Ind=pop();
puss(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
WHILEST: WHILELOOP{
Ind=pop();
sprintf(QUAD[Ind].result,"%d",StNo);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
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);
}
main()
{
int a,b,c;
if(a<b)
{ a=a+b; }
while(a<b)
{ a=a+b; }
if(a<=b)
{
c=a-b;
}
else
{
c=a+b;
}
}
OUTPUT:
C:\GnuWin32\bin>flex bnf.l
C:\GnuWin32\bin>a.exe test.c
0 < a b t0
1 == t0 FALSE 5
2 + a b t1
3 = t1 a
4 GOTO 5
5 < a b t2
6 == t2 FALSE 10
7 + a b t3
8 = t3 a
9 GOTO 5
10 <= a b t4
11 == t4 FALSE 15
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t6
16 = t6 c
RESULT:
Thus the program for the exercise on the syntax using YACC has been executed successfully
and output is verified.
EX.NO:6
DATE:
INTRODUCTION:
The type analysis and type checking is an important activity done in the semantic
analysis phase. The need for type checking is
program parser
code
ALGORITHM:
1. Start a program.
4. Get the expression from the user and separate into the tokens.
Type.c
#include<stdio.h>
#include<conio.h>
#include<string.h>
struct symbol{
char name[10],type[10];
}s[10];
void main(){
int i=0,k=0,l=0,m=0,flag=0;
char temp[50],temp1[50],t1[50],b[10],c[10],str[50],buf[50];
char *a[10]={"int","float","char","double"};
char *op[10]={"+","-","*","/","<",">"};
FILE *fp;
clrscr();
fp=fopen("sample.c","r");
while(!feof(fp))
{ fscanf(fp,"%s",str);
//printf("%s\n",str);
for(i=0;i<4;i++)
{
if(strcmp(str,a[i])==0)
{
strcpy(s[k].type,str);
fscanf(fp,"%s",buf);
strcpy(s[k].name,buf);
k++;
/*if(buf!=","||buf!=";")
{
strcpy(s[k].name,buf);
k++;
} */
}
}
}
printf("symbol table\n");
for(k=0;k<10;k++)
{ printf("%s\t%s\t\n",s[k].type,s[k].name);
}
fclose(fp);
fp=fopen("sample.c","r");
while(!feof(fp))
{ fscanf(fp,"%s",temp);
//printf("%s\n",temp);
strcpy(t1,temp);
fscanf(fp,"%s",temp);
//printf("%s\n",temp);
//getch();
for(l=0;l<10;l++)
{ if(strcmp(temp,op[l])==0)
{ //printf("\n%s\n",t1);
//printf("%s\n",temp);
fscanf(fp,"%s",temp1);
//printf("%s\n",temp1);
for(m=0;m<10;m++)
{
if(strcmp(t1,s[m].name)==0)
strcpy(b,s[m].type);
if(strcmp(temp1,s[m].name)==0)
strcpy(c,s[m].type);
flag=1;
} }
//printf("\nFlag=%d",flag);
if(flag==1)
{
if(strcmp(b,c)==0)
printf("valid");
else
printf("invalid");
flag=0;
} } }
getch();
}
INPUT:
Sample.c
main ()
int a ;
float b ;
if ( a < b )
OUTPUT:
invalid
RESULT:
Thus the program has been executed successfully and Output is verified.
EX.NO:7A
DATE:
AIM:
INTRODUCTION:
Control flow analysis can be represent by basic blocks. It depicts how th program
control is being passed among the blocks.
ALGORITHM:
3. Get the choice to insert, delete and display the values in stack
a. t = newnode()
c. Read n
d. t ->info= n
e. t ->next=top
f. top = t
g. Return
a. If (top=NULL)
b. Print”underflow”
c. Return
d. X=top
e. Top=top->next
f. Delnode(x)
g. Return
Controlflow.c
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
int i,flag,count=0;
char *a[2]={"for","while"}; /* loop keywords */
char c,str[10],temp[10],index[10];
FILE *fp;
clrscr();
fp=fopen("file2.c","r");
do
{
fscanf(fp,"%s",str);
for(i=0;i<2;i++)
{
if(strcmp(str,a[i])==0)
{ fscanf(fp,"%s",temp);
fscanf(fp,"%s",temp);
strcpy(index,temp);
}
}
}while(strcmp(str,"{")!=0);
printf("%s",str);
printf("%s",index);
while(!feof(fp))
{
flag=0;
fscanf(fp,"%s",str);
if(strcmp(str,"}")==0) break;
count++;
do
{
if(strcmp(str,index)==0)
flag++;
fscanf(fp,"%s",str);
}while(strcmp(str,";")!=0);
if(flag!=0)
printf("%d has a variant variable\n",count);
else
printf("%d has a invariant variable\n",count);
}
getch();
}
Input
file2.c
While ( i < 3 )
{ j = i ++ ;
k = 10 ;
}
Output
1 has a variant variable
2 has a invariant variable
RESULT:
Thus the C program to implement control flow analysis was executed successfully.
EX.NO:7B
DATE:
AIM:
INTRODUCTION:
Data flow analysis is a technique for gathering information about the possible set
of value calculated at various points in a computer program.
ALGORITHM:
3. Get the choice to insert, delete and display the values in stack
a. t = newnode()
c. Read n
d. t ->info= n
e. t ->next=top
f. top = t
g. Return
a. If (top=NULL)
b. Print”underflow”
c. Return
d. X=top
e. Top=top->next
f. Delnode(x)
g. Return
Dataflow.c
#include<stdio.h>
#include<conio.h>
void main()
{
FILE *fp;
int count,k;
char c,ch;
clrscr();
count=1;
fp = fopen("file.c","r");
for(c=getc(fp);c!=EOF;c=getc(fp))
{
if(c=='\n')
{
count=count+1;
printf("\nline: %d\t",count);
}
else
{
printf("%c",c);
}
}
fclose(fp);
fp=fopen("fileee.c","r");
printf("\n enter the variable to check for Liveness:\n");
scanf("%c",&ch);
count=1;
for(c=getc(fp);c!=EOF;c=getc(fp))
{
if(c=='\n'&&c!=ch)
{
count=count+1;
}
else if(strcmp(c,ch)==0)
{
printf("%d\t",count);
}
}
fclose(fp);
getch();
}
Input
file.c
{
int a , b ;
a=0;
b=a+1;
a=3;
a=a+b;
}
Output
enter the variable to check for Liveness: b
246
RESULT:
Thus the C program to implement data flow analysis was executed successfully.
EX.NO:8
DATE:
INTRODUCTION:
Storage Allocation
Runtime environment manages runtime memory requirements for the following entities:
Code: It is known as the part of a program that does not change at runtime. Its
memory requirements are at the compile time
Procedures: Their text part is static but they are called in a random manner. That is
why, stack storage is used to manage procedure calls and activations.
Variables: Variables are known at the runtime only, unless they are global or
constant. Heap memory allocation scheme is used for managing allocation and de-
allocation of memory for variables in runtime.
ALGORITHM:
3. If the length of the string is greater than 3, than call the procedure to return
the precedence
4. Among the operands.
Heap.c
#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);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()
{
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();
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();
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)
{ 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();
}}
OUTPUT:
Dag.c
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
int node_gen_number=0;
struct node
{ int node_no;
char label; /* id : i, num : n */
int l_child; /* 0 : No entry */
int r_child; /* 0 : No entry */
char entry;
int disp;
struct node *next;
};
struct node* mkleafnode(char type,char entry)
{ struct node *n;
n=malloc(sizeof(struct node));
n->label=type;
n->entry=entry;
n->l_child=0;
n->r_child=0;
n->next=NULL;
n->disp=0;
return(n); }
struct node* mknode(char type,int l,int r)
{ struct node *n;
n=malloc(sizeof(struct node));
n->label=type;
n->l_child=l;
n->r_child=r;
n->entry='!';
n->next=NULL;
n->disp=0;
return(n); }
struct node* comparenode(struct node *first,struct node *second)
{ while(first!=NULL)
{ if(first->label==second->label&&first->l_child==second->l_child&&first-r_child==
second->r_child&&first->entry=='!'&&second->entry=='!')
{ free(second);
return(first); }
else
if(first->l_child==0&&second->l_child==0&&first->label==second->label&&first-
>entry==second->entry)
{ free(second);
return(first); }
first=first->next; }
second->node_no=++node_gen_number;
return(second); }
struct node* findnode(struct node *first,char check)
{ while(first!=NULL)
if(first->entry==check)
return(first);
else
first=first->next;
return(NULL); }
struct node* find_node(struct node *first,int no)
{ while(first!=NULL)
if(first->node_no==no)
return(first);
else
first=first->next;
return(NULL); }
void display(struct node *tree,struct node *curr)
{ struct node *temp;
if(curr->entry=='!')
printf("\t\t%d\t%c\t%d\t\t%d\n",curr->node_no,curr->label,curr->l_child,curr->r_child);
else
printf("\t\t%d\t%c\t%c\t\t-\n",curr->node_no,curr->label,curr->entry);
if(curr->l_child!=0&&curr->r_child!=0)
{ temp=find_node(tree,curr->l_child);
if(temp->disp!=1)
{ temp->disp=1;
display(tree,temp); }
temp=find_node(tree,curr->r_child);
if(temp->disp!=1)
{ temp->disp=1;
display(tree,temp); } } }
void main()
{
int i,j,ip=0;
char input[30];
struct node *head=NULL,*temp,*check,*tail;
struct node *tree=NULL;
clrscr();
printf("\t\tConstruction of Directed Acyclic Graph.\n\n");
printf("Enter the Input String: ");
scanf("%s",input);
while(input[ip]!='\0')
{
if(input[ip]!='+'&&input[ip]!='-'&&input[ip]!='*'&&input[ip]!='/')
{ if(isalpha(input[ip]))
temp=mkleafnode('i',input[ip]);
else
temp=mkleafnode('n',input[ip]);
check=comparenode(head,temp);
if(head==NULL)
{ head=temp;
tail=temp; }
else
if(temp==check)
{ tail->next=temp;
tail=temp; } }
ip++;
} ip=0;
while(input[ip]!='\0')
{ if(input[ip]=='+'||input[ip]=='-'||input[ip]=='*'||input[ip]=='/')
{
if(tree==NULL)
{ temp=findnode(head,input[ip-1]);
check=findnode(head,input[ip+1]);
temp=mknode(input[ip],temp->node_no,check- >node_no); }
else {
temp=findnode(head,input[ip+1]);
temp=mknode(input[ip],tail->node_no,temp->node_no); }
check=comparenode(tree,temp);
if(tree==NULL)
{ tree=temp;
tail=temp; }
else
if(temp==check)
{ tail->next=temp;
tail=temp; }
} ip++; }
temp=head;
while(temp!=NULL)
{ check=temp;
temp=temp->next; }
check->next=tree;
printf("\n\n\t\tNode\tLabel\tl_Child|Entry\tR_child\n\n");
display(head,tail);
getch(); }
OUTPUT:
Node
1_Child|Entry R_child
Label
5 + 4 2
4 * 3 1
3 + 1 2
1 i a -
2 i b -
Ex. No: 10 Implement the back end of the compiler (Or) Implementation of Code Generator
Code.c
#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++)
{ 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;
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();
}
}
OUTPUT:
#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)
{ 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 Elimination");
for(k=0;k<z;k++)
{ printf("%c\t=",pr[k].l);
printf("%s\n",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); } }
getch(); }
OUTPUT: