Compiler Design Lab Record
Compiler Design Lab Record
ODD SEMSTER
NAME: ___________________________________________________________________
ROLL NO:__________________________________________________________________
BRANCH:__________________ SEM:______________________________________
Page 1 of 31
lOMoAR cPSD| 25453444
641104
Name :……………………………………………………………………………
Register Number:………………………………………………………………………….
Department :…………………………………………………………………………….
Page 2 of 31
lOMoAR cPSD| 25453444
INDEX
S.No Date List of Experiment Page No Marks Sign
Page 3 of 31
lOMoAR cPSD| 25453444
LIST OF EXPERIMENTS:
1. Using the LEX tool, Develop a lexical analyzer to recognize a few patterns in C.
(Ex.Identifiers, constants, comments, operators etc.). Create a symbol table, while
recognizing Identifiers.
4. Generate three address codes for a simple program using LEX and YACC.
7. Implement back-end of the compiler for which the three address code is given as input
and the 8086 assembly language code is produced as output.
PRACTICALS 30 PERIODS
Page 4 of 31
lOMoAR cPSD| 25453444
AIM:
To Create a Lexical Analyzer using C programming and to create lexemes that is grouped
into various categories.
ALGORITHM:
Step 1: Start the program.
Step 2: Create some character arrays to store and manipulate the characters.
Step 3: Create a file pointer and get the name of the input file to read the input from.
Step 4: Open the input file using the read category.
Step 5: Copy the content of the file into a string and then copy it to a character array for processing.
Step 6: Use a while loop and browse the content of the file till the end.
Step 7: Using a if condition, Separate some symbols like ;<>{}()#,& and print them as Special
Characters.
Step 8: Using a if condition, print the letters/words following the int, char or float as the Variables.
Step 9: Using a if condition, print the words printf, scanf, main, void etc as the keywords.
Step 10: Terminate the program.
PROGRAM:
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void main()
{
int i=0,j=0,x=0,n;
void *p,*add[5];
char ch,srch,b[15],d[15],c;
printf("Expression terminated by $:");
while((c=getchar())!='$')
{
b[i]=c;
i++;
}
n=i-1;
printf("Given Expression:");
Page 5 of 31
lOMoAR cPSD| 25453444
i=0;
while(i<=n)
{
printf("%c",b[i]);
i++;
}
printf("\n Symbol Table\n");
printf("Symbol \t addr \t type");
while(j<=n)
{
c=b[j];
if(isalpha(toascii(c)))
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("\n%c \t %d \t identifier\n",c,p);
x++;
j++;
}
else
{
ch=c;
if(ch=='+'||ch=='-'||ch=='*'||ch=='=')
{
p=malloc(ch);
add[x]=p;
d[x]=ch;
printf("\n %c \t %d \t operator\n",ch,p);
x++;
j++;
}}}}
Page 6 of 31
lOMoAR cPSD| 25453444
OUTPUT:
RESULT:
Thus the C program to implement the Lexical Analyzer is done and the required Lexemes
are obtained and the output is verified.
Page 7 of 31
lOMoAR cPSD| 25453444
AIM:
To implement a Lexical Analyzer using a Lex Tool to divide the lexemes into various
categories.
ALGORITHM:
Step 1: Start the program.
Step 2: Include the header files needed.
Step 3: Use a if condition for separating the keywords like int,char,float,return.
Step 4: Use another if condition for separating the preprocessor directives like #.*
Step 5: Use another if condition for separating the function names like main,printf,scanf.
Step 6: Use another if condition for separating the letters and words as identifiers.
Step 7: Use another if condition for separating the operators like +-/*%
Step 8: Use another if condition for separating the Special characters like ,;&{}()
Step 9: Terminate the program.
PROGRAM:
lextool.l
Page 8 of 31
lOMoAR cPSD| 25453444
typedef
| return
| else |
goto {printf("\n\t%s is a
KEYWORD",yytext);} "/*" {COMMENT
= 1;}
"*/" {COMMENT = 0; cnt++;}
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n BLOCK ENDS");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER",yytext);}
\".*\" {if(!COMMENT) printf("\n\t%s is a
STRING",yytext);} [0-9]+ {if(!COMMENT) printf("\n\t
%s is a NUMBER",yytext);}
\)(\;)? {if(!COMMENT) printf("\n\t");ECHO;printf("\n");}
\( ECHO;
= {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
int main(int argc,char **argv)
{
if (argc > 1)
{
FILE *file;
file =
fopen(argv[1],"r");
if(!file)
{
printf("could not open %s \
n",argv[1]); exit(0);
}
yyin = file;
}
yylex();
printf("\n\n Total No.Of comments are
%d",cnt); return 0;
}
int yywrap()
{
return 1;
Page 9 of 31
lOMoAR cPSD| 25453444
OUTPUT:
RESULT:
Thus the required Lexical Analyzer is designed and the required output is obtained and
verified.
Page 10 of 31
lOMoAR cPSD| 25453444
AIM:
To write a program to recognize a valid arithmetic expression that uses operator +, - ,
* and / using YACC tool.
ALGORITHM:
LEX
Step 1: Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
Step 2: LEX requires regular expressions to identify valid arithmetic expression token of lexemes.
Step 3: LEX call yy wrap() function after input is over. It should return 1 when work is
done Or should return 0 when more processing is required.
YACC
Step 1: Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
Step 2: Define tokens in the first section and also define the associativity of the operations
Step 3: Mention the grammar productions and the action for each production.
Step 4: $$ refer to the top of the stack position while $1 for the first value, $2 for the second
Value in the stack.
Step 5: Call yyparse() to initiate the parsing process
Step 6: yyerror() function is called when all productions in the grammar in second section
doesn't match to the input statement.
PROGRAM:
arithmetic.l
%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[a-zA-Z][0-9a-zA-Z]* {return ID;}
[0-9]+ {return DIG;}
[ \t]+ {;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap()
{
return 1;
}
arithmetic.y
%{
#include<stdio.h>
%}
%token ID DIG
%left '+''-'
%left '*''/'
Page 11 of 31
lOMoAR cPSD| 25453444
%right UMINUS
%%
stmt:expn ;
expn:expn'+'expn
|expn'-'expn
|expn'*'expn
|expn'/'expn
|'-'expn %prec UMINUS
|'('expn')'
|DIG
|ID
;
%%
int main()
{
printf("Enter the Expression \n");
yyparse();
printf("valid Expression \n");
return 0;
}
int yyerror()
{
printf("Invalid Expression");
exit(0);
}
OUTPUT:
RESULT:
Thus a calculator is formed using Yacc and the expressions are checked and the output of
the valid expressions are obtained and verified successfully.
Page 12 of 31
lOMoAR cPSD| 25453444
Date :
AIM:
To write a yacc program to check valid variable followed by letter or digits
ALGORITHM:
Step3: Checking the validating of the given expression according to the rule using yacc.
Step4: Using expression rule print the result of the given values
PROGRAM:
LEX PART:
%{
#include "y.tab.h"
%}
%%
. return yytext[0];
\n return 0;
%%
int yywrap()
return 1;
Page 13 of 31
lOMoAR cPSD| 25453444
YACC PART:
%{
#include<stdio.h>
int valid=1;
%}
%%
start : letter s
s : letter s
| digit s
%%
int yyerror()
valid=0;
return 0;
int main()
if(valid)
printf("\nIt is a identifier!\n");
Page 14 of 31
lOMoAR cPSD| 25453444
OUTPUT:
RESULT:
Thus the Program was executed successfully.
Page 15 of 31
lOMoAR cPSD| 25453444
AIM:
To write a yacc program to check valid Control Structures followed by Loop Conditions
ALGORITHM:
Step3: Checking the validating of the given expression according to the rule using yacc.
Step4: Using expression rule print the result of the given values
PROGRAM:
loop.l
%{
/* Definition section */
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
%}
/* %option noyywrap */
/* Rule Section */
%%
%%
int yywrap()
{
return -1;
}
Page 16 of 31
lOMoAR cPSD| 25453444
loop.y
%{
/* Definition section */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern int yylex();
int i;
int k =0;
%}
%union {
char* f;
}
/* Rule Section */
%%
S:E {
flag = 0;
k = strlen($1) - 1;
if(k%2==0){
}else{
}
}
Page 17 of 31
lOMoAR cPSD| 25453444
%%
//driver code
int main()
{
yyparse();
return 0;
}
OUTPUT
RESULT:
Thus the Program was executed successfully.
Page 18 of 31
lOMoAR cPSD| 25453444
AIM:
To write a yacc program to check Calculator application
ALGORITHM:
Step3: Checking the validating of the given expression according to the rule using yacc.
Step4: Using expression rule print the result of the given values
PROGRAM:
calc.l
%{
/* Definition section */
#include<stdio.h>
#include "y.tab.h"
extern int yylval;
%}
/* Rule Section */
%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;
}
[\t] ;
[\n] return 0;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
Page 19 of 31
lOMoAR cPSD| 25453444
calc.y
%{
/* Definition section */
#include<stdio.h>
int flag=0;
%}
%token NUMBER
%left '+' '-'
/* Rule Section */
%%
ArithmeticExpression: E{
printf("\nResult=%d\n", $$);
return 0;
};
E:E'+'E {$$=$1+$3;}
|E'-'E {$$=$1-$3;}
|E'*'E {$$=$1*$3;}
|E'/'E {$$=$1/$3;}
|E'%'E {$$=$1%$3;}
|'('E')' {$$=$2;}
| NUMBER {$$=$1;}
;
%%
//driver code
void main()
{
printf("\nEnter Any Arithmetic Expression
which can have operations Addition,
Subtraction, Multiplication, Division,
Modulus and Round brackets:\n");
yyparse();
if(flag==0)
printf("\nEntered arithmetic expression is Valid\n\n");
}
Page 20 of 31
lOMoAR cPSD| 25453444
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
flag=1;
}
OUTPUT :
RESULT:
Thus the Program was executed successfully.
Page 21 of 31
lOMoAR cPSD| 25453444
Ex.No.4 Generate three address code for a simple program using LEX and
YACC Date :
AIM:
To write a Lex and yacc program to check statements for three address code
ALGORITHM:
Step2: Get Three Variables from statements and stored in the text file
Step3: Compile the program and give the path of source file.
PROGRAM :
three.l
%{
#include<stdio.h>
#include"y.tab.h"
int k=1;
%}
%%
[0-9]+ {
yylval.dval=yytext[0];
return NUM;
}
\n {return 0;}
. {return yytext[0];}
%%
Page 22 of 31
lOMoAR cPSD| 25453444
int yywrap()
{
return 1;
}
main()
{
yyparse();
return 0;
}
three.y
%{
#include<stdio.h>
int aaa;
%}
%union{ ch
ar dval;
}
%%
statement : E {printf("\nt = %c \n",$1);}
;
E : E '+' E
{
char word[]="t";
char *test=gencode(word,$1,'+',$3);
$$=test;
}
| E '-' E
{
char word[]="t";
char *test=gencode(word,$1,'-',$3);
$$=test;
}
| E '%' E
{
char word[]="t";
char *test=gencode(word,$1,'%',$3);
$$=test;
}
| E '*' E
{
Page 23 of 31
lOMoAR cPSD| 25453444
char word[]="t";
char *test=gencode(word,$1,'*',$3);
$$=test;
}
| E '/' E
{
char word[]="t";
char *test=gencode(word,$1,'/',$3);
$$=test;
}
| '(' E ')'
{
$$=$2;
}
| NUM
{
$$=$1;
}
;
%%
OUTPUT
RESULT:
Thus the Program was executed successfully.
Page 24 of 31
lOMoAR cPSD| 25453444
AIM:
To write a Lex and yacc program to type check the given statements
ALGORITHM:
Step2: Get Three Variables from statements and stored in the text file
Step3: Compile the program and give the path of source file.
PROGRAM
type.l
%{
%}
%s A B C DEAD
%%
<INITIAL>[0-9]+ BEGIN A;
<INITIAL>[0-9]+[.][0-9]+ BEGIN B;
<INITIAL>[A-Za-z_][A-Za-z0-9_]* BEGIN C;
<INITIAL>[^\n] BEGIN DEAD;
<INITIAL>\n BEGIN INITIAL; {printf("Not Accepted\n");}
<A>[^\n] BEGIN DEAD;
<A>\n BEGIN INITIAL; {printf("Integer\n");}
<B>[^\n] BEGIN DEAD;
<B>\n BEGIN INITIAL; {printf("Float\n");}
<C>[^\n] BEGIN DEAD;
<C>\n BEGIN INITIAL; {printf("Identifier\n");}
<DEAD>[^\n] BEGIN DEAD;
<DEAD>\n BEGIN INITIAL; {printf("Invalid\n");}
%%
int yywrap()
{
return 1;
}
int main()
{
printf("Enter String\n");
yylex();
return 0;
}
Page 25 of 31
lOMoAR cPSD| 25453444
OUTPUT :
RESULT:
Thus the Program was executed successfully.
Page 26 of 31
lOMoAR cPSD| 25453444
AIM:
To write a C Program to implement the code optimization techniques
ALGORITHM:
PROGRAM
code.c
#include<stdio.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;
printf("Enter the Number of
Values:"); scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
scanf(" %c",&op[i].l);
printf("right: ");
scanf(" %s",&op[i].r);
}
printf("Intermediate Code\n") ;
for(i=0;i<n;i++)
Page 27 of 31
lOMoAR cPSD| 25453444
{
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\n");
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\n",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);
}
Page 28 of 31
lOMoAR cPSD| 25453444
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';
}
}
}
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);
}
}
}
OUTPUT :
RESULT:
Thus the Program was executed successfully.
Page 29 of 31
lOMoAR cPSD| 25453444
Ex.No.7 Implement back-end of the compiler for which the three address code is
given as input and the 8086 assembly language code is produced as output.
Date :
AIM:
To implement the back end of a compiler which takes the three address code and produces
the 8086 assembly language instructions using a C program.
ALGORITHM:
Step 1: Start the program.
Step 2: Include the necessary header files.
Step 3: Declare necessary character arrays for input and output and also a structure to include it.
Step 4: Get the Intermediate Code as the input.
Step 5: Display the options to do the various operations and use a switch case to implement that
operation.
Step 6: Terminate the program.
PROGRAM:
#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 '/':
Page 30 of 31
lOMoAR cPSD| 25453444
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:
RESULT:
Thus the required C program to implement the back end of the compiler is done and the required
output is obtained and verified.
Page 31 of 31