Compiler Design Lab Manual
Compiler Design Lab Manual
com
CD LAB PROGRAMS
DEPARTMENT OF
COMPUTER SCIENCE AND ENGINEERING
L D
Compiler Design
Lab Manual
O R
U W
N T
J Prepared by
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
TABLE OF CONTENTS
(As per syllabus)
S.N Wee Page
TOPIC
o k No.
System Requirements 3
1
Lab Objectives 4
2
Design a lexical analyzer for given language .the lexical
5
3 analyzer should ignore redundant spaces, tabs and new lines.
Implement the lexical analyzer using JLex, flex or other
lexical analyzer generating tools. 8
4
6
Design a LALR bottom up parser for the given language
L D 16
R
Convert the BNF rules into Yacc form and write code to
generate abstract syntax tree. 18
7
8
A program to generate machine code
O 25
U W
10
11
N T
12
13
J
14
15
16
17
18
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
System Requirements
L D
O R
U W
N T
J
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
Lab Objectives
L D
O R
U W
N T
J
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
#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;
L D
char c,str[10],st1[10];
f1=fopen("input","w");
while((c=getchar())!=EOF) O
printf("\nEnter the c program");/*gets(st1);*/ R
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
putc(c,f1);
fclose(f1);
f1=fopen("input","r");
U W
T
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
N
while((c=getc(f1))!=EOF)
{
J 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);
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
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);
L D
printf("\nThe no's in the program are");
for(j=0;j<i;j++)
printf("%d",num[j]);
printf("\n");
O R
f2=fopen("identifier","r");
k=0;
U W
printf("The keywords and identifiersare:");
while((c=getc(f2))!=EOF)
{
N T
if(c!=' ')
str[k++]=c;
Jelse
{
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);
}
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
Output:
Ctrl-D
L D
R
Total no. of lines are: 1
O
U W
N T
J
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
%%
D
int |
float |
char |
double |
while |
for |
R L
do |
if | O
break |
continue |
void |
U W
switch |
case |
long |
N T
struct |
const |
typedef |
return |
else |
J
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}
/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
\( ECHO;
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
L D
int main(int argc,char **argv)
{
if (argc > 1)
{
O R
FILE *file;
file = fopen(argv[1],"r");
if(!file)
{
U W
}
exit(0);
N T
printf("could not open %s \n",argv[1]);
}
yyin = file;
yylex();
J
printf("\n\n");
return 0;
}
int yywrap()
{
return 0;
}
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
Input:
$vi var.c
#include<stdio.h>
main()
{
int a,b;
}
Output:
$lex lex.l
$cc lex.yy.c
$./a.out var.c
L D
FUNCTION
O R
#include<stdio.h> is a PREPROCESSOR DIRECTIVE
main (
U W
BLOCK BEGINS
N
int is a KEYWORD
T
J
a IDENTIFIER
b IDENTIFIER
BLOCK ENDS
10
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#define SIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 257
#define KEYWORD 258
#define ID 259
#define DONE 260
#define MAX 999
char lexemes[MAX];
char buffer[SIZE];
int lastchar=-1;
int lastentry=0;
L D
int tokenval=DONE;
int lineno=1;
int lookahead;
struct entry
{ O R
char *lexptr;
int token;
}symtable[100];
U W
struct entry
T
keywords[]={"if",KEYWORD,"else",KEYWORD,"for",KEYWORD,"int",KEYWORD,
N
"float",KEYWORD,"double",KEYWORD,"char",KEYWORD,"struct",KEYWORD,"ret
J
urn",KEYWORD,0,0};
void Error_Message(char *m)
{
fprintf(stderr,"line %d, %s \n",lineno,m);
exit(1);
}
int look_up(char s[ ])
{
int k;
for(k=lastentry;k>0;k--)
if(strcmp(symtable[k].lexptr,s)==0)
return k;
return 0;
}
int insert(char s[ ],int tok)
{
int len;
11
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
len=strlen(s);
if(lastentry+1>=MAX)
Error_Message("Symbpl table is full");
if(lastchar+len+1>=MAX)
Error_Message("Lexemes array is full");
lastentry=lastentry+1;
symtable[lastentry].token=tok;
symtable[lastentry].lexptr=&lexemes[lastchar+1];
lastchar=lastchar+len+1;
strcpy(symtable[lastentry].lexptr,s);
return lastentry;
}
/*void Initialize()
{
struct entry *ptr;
for(ptr=keywords;ptr->token;ptr+1)
}*/
insert(ptr->lexptr,ptr->token);
int lexer()
L D
{
int t;
int val,i=0;
while(1)
O R
{
t=getchar();
if(t==' '||t=='\t');
else if(t=='\n')
U W
lineno=lineno+1;
N T
else if(isdigit(t))
{
}
J
ungetc(t,stdin);
scanf("%d",&tokenval);
return NUM;
else if(isalpha(t))
{
while(isalnum(t))
{
buffer[i]=t;
t=getchar();
i=i+1;
if(i>=SIZE)
Error_Message("Compiler error");
}
buffer[i]=EOS;
if(t!=EOF)
12
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
ungetc(t,stdin);
val=look_up(buffer);
if(val==0)
val=insert(buffer,ID);
tokenval=val;
return symtable[val].token;
}
else if(t==EOF)
return DONE;
else
{
tokenval=NONE;
return t;
}
}
}
void Match(int t)
{
if(lookahead==t)
L D
}
lookahead=lexer();
else
Error_Message("Syntax error");
O R
void display(int t,int tval)
{
if(t=='+'||t=='-'||t=='*'||t=='/')
U W
printf("\nArithmetic Operator: %c",t);
else if(t==NUM)
N T
printf("\n Number: %d",tval);
else if(t==ID)
}
else
J
printf("\n Identifier: %s",symtable[tval].lexptr);
void F()
{
//void E();
switch(lookahead)
{
case '(' : Match('(');
E();
Match(')');
break;
case NUM : display(NUM,tokenval);
Match(NUM);
break;
13
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
case ID : display(ID,tokenval);
Match(ID);
break;
default : Error_Message("Syntax error");
}
}
void T()
{
int t;
F();
while(1)
{
switch(lookahead)
{
case '*' : t=lookahead;
Match(lookahead);
F();
display(t,NONE);
continue;
L D
case '/' : t=lookahead;
Match(lookahead);
display(t,NONE);
continue;
O R
}
}
}
default : return;
U W
void E()
{
int t;
N T
T();
while(1)
{
J
switch(lookahead)
{
case '+' : t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
case '-' : t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
default : return;
14
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
}
}
}
void parser()
{
lookahead=lexer();
while(lookahead!=DONE)
{
E();
Match(';');
}
}
main()
{
char ans[10];
printf("\n Program for recursive decent parsing ");
printf("\n Enter the expression ");
printf("And place ; at the end\n");
printf("Press Ctrl-Z to terminate\n");
L D
}
parser();
Output:
O R
Program for recursive decent parsing
U W
Enter the expression And place ; at the end
a+b*c;
Identifier: a
N T
Press Ctrl-Z to terminate
Identifier: b
Identifier: c
J
Arithmetic Operator: *
Arithmetic Operator: +
2*3;
Number: 2
Number: 3
Arithmetic Operator: *
+3;
line 5,Syntax error
Ctrl-Z
15
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
<parser.l>
%{
#include<stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ {yylval.dval=atof(yytext);
return DIGIT;
}
\n|. return yytext[0];
%%
%{
<parser.y>
L D
%}
#include<stdio.h>
O R
/*This YACC specification file generates the LALR parser for the program
considered in experiment 4.*/
%union
{
double dval;
U W
T
}
16
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
| DIGIT
;
%%
int main()
{
yyparse();
}
yyerror(char *s)
{
printf("%s",s);
}
Output:
$lex parser.l
$yacc –d parser.y
L D
$cc lex.yy.c y.tab.c –ll –lm
$./a.out
2+3
5.0000 O R
U W
N T
J
17
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
5) Convert The BNF rules into Yacc form and write code to
generate abstract syntax tree.
<int.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]+)
%%
if return IF;
L D
else
while
int |
return ELSE;
return WHILE;
O R
char |
float return TYPE;
U W
{identifier} {strcpy(yylval.var,yytext);
{number}
N T
return VAR;}
{strcpy(yylval.var,yytext);
\< |
\> |
J
return NUM;}
\>= |
\<= |
== {strcpy(yylval.var,yytext);
return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%
18
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
<int.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;
L D
extern int LineNo;
%}
%union
{ O R
}
char var[10];
%%
J
PROGRAM : MAIN BLOCK
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
19
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
| CONDST
| WHILEST
;
;
}
strcpy($$,QUAD[Index++].result);
L D
O R
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
U W
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR
;
| NUM
N T
CONDST: IFST{
Ind=pop();
J
sprintf(QUAD[Ind].result,"%d",Index);
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
20
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
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);
sprintf(QUAD[Ind].result,"%d",Index);
}
BLOCK{
L D
Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
;
O R
}
StNo=Index-1;
U W
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$);
| VAR
| NUM
;
N T
J
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 {
21
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
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)
{
L D
}
printf("\n File not found");
exit(0);
yyin=fp;
O R
}
yyparse();
U W
printf("\n\n\t\t ----------------------------""\n\t\t Pos Operator Arg1 Arg2 Result" "\n\t\t
--------------------");
for(i=0;i<Index;i++)
{
N T
printf("\n\t\t %d\t %s\t %s\t %s\t
}
J
%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;
}
22
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
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);
L D
yyerror()
{
}
printf("\n Error on line no:%d",LineNo);
O R
Input:
U W
$vi test.c
main()
{
N T
int a,b,c;
if(a<b)
{
a=a+b;
J
}
while(a<b)
{
a=a+b;
}
if(a<=b)
{
c=a-b;
}
else
{
c=a+b;
23
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
}
}
Output:
$lex int.l
$yacc –d int.y
$gcc lex.yy.c y.tab.c –ll –lm
$./a.out test.c
0 < a b to
1 == to FALSE 5
2 + a b
L D
t1
R
3 = t1 a
O
4 GOTO 5
5 < a b t2
6 == t2
U W FALSE 10
8
+
=
N T a
t3
b t3
10
JGOTO
<= a b t4
5
11 == t4 FALSE 15
12 - a b t5
13 = t5 c
14 GOTO 17
15 + a b t3
16 = t6 c
___________________________________________________
24
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int label[20];
int no=0;
int main()
{
FILE *fp1,*fp2;
char fname[10],op[10],ch;
char operand1[8],operand2[8],result[8];
int i=0,j=0;
printf("\n Enter filename of the intermediate code");
scanf("%s",&fname);
fp1=fopen(fname,"r");
fp2=fopen("target.txt","w");
if(fp1==NULL || fp2==NULL)
L D
{
}
printf("\n Error opening the file");
exit(0);
while(!feof(fp1)) O R
{
fprintf(fp2,"\n");
fscanf(fp1,"%s",op);
U W
i++;
T
if(check_label(i))
N
fprintf(fp2,"\nlabel#%d",i);
{
J
if(strcmp(op,"print")==0)
fscanf(fp1,"%s",result);
fprintf(fp2,"\n\t OUT %s",result);
}
if(strcmp(op,"goto")==0)
{
fscanf(fp1,"%s %s",operand1,operand2);
fprintf(fp2,"\n\t JMP %s,label#%s",operand1,operand2);
label[no++]=atoi(operand2);
}
if(strcmp(op,"[]=")==0)
{
fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n\t STORE %s[%s],%s",operand1,operand2,result);
}
if(strcmp(op,"uminus")==0)
25
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
{
fscanf(fp1,"%s %s",operand1,result);
fprintf(fp2,"\n\t LOAD -%s,R1",operand1);
fprintf(fp2,"\n\t STORE R1,%s",result);
}
switch(op[0])
{
case '*': fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n \t LOAD",operand1);
fprintf(fp2,"\n \t LOAD %s,R1",operand2);
fprintf(fp2,"\n \t MUL R1,R0");
fprintf(fp2,"\n \t STORE R0,%s",result);
break;
case '+': fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n \t LOAD %s,R0",operand1);
fprintf(fp2,"\n \t LOAD %s,R1",operand2);
fprintf(fp2,"\n \t ADD R1,R0");
fprintf(fp2,"\n \t STORE R0,%s",result);
break;
L D
O R
case '-': fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n \t LOAD %s,R0",operand1);
fprintf(fp2,"\n \t LOAD %s,R1",operand2);
fprintf(fp2,"\n \t SUB R1,R0");
U W
fprintf(fp2,"\n \t STORE R0,%s",result);
break;
case '/': fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n \t LOAD %s,R0",operand1);
N T
fprintf(fp2,"\n \t LOAD %s,R1",operand2);
fprintf(fp2,"\n \t DIV R1,R0");
fprintf(fp2,"\n \t STORE R0,%s",result);
J
break;
case '%': fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n \t LOAD %s,R0",operand1);
fprintf(fp2,"\n \t LOAD %s,R1",operand2);
fprintf(fp2,"\n \t DIV R1,R0");
fprintf(fp2,"\n \t STORE R0,%s",result);
break;
case '=': fscanf(fp1,"%s %s",operand1,result);
fprintf(fp2,"\n\t STORE %s %s",operand1,result);
break;
case '>': j++;
fscanf(fp1,"%s %s %s",operand1,operand2,result);
fprintf(fp2,"\n \t LOAD %s,R0",operand1);
fprintf(fp2,"\n\t JGT %s,label#%s",operand2,result);
label[no++]=atoi(result);
break;
26
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
O R
int check_label(int k)
{
int i;
for(i=0;i<no;i++)
U W
{
if(k==label[i])
return 1;
N T
}
}
return 0;
J
Input:
$vi int.txt
=t1 2
[]=a 0 1
[]=a 1 2
[]=a 2 3
*t1 6 t2
+a[2] t2 t3
27
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
-a[2] t1 t2
/t3 t2 t2
uminus t2 t2
print t2
goto t2 t3
=t3 99
uminus 25 t2
*t2 t3 t3
uminus t1 t1
+t1 t3 t4
print t4
Output:
STORE t1,2
STORE a[0],1
STORE a[1],2
L D
STORE a[2],3
LOAD t1,R0
LOAD 6,R1 O R
ADD R1,R0
STORE R0,t3
U W
LOAD a[2],R0
LOAD t2,R1
ADD R1,R0
N T
STORE R0,t3
LOAD a[t2],R0
LOAD t1,R1
SUB R1,R0
J
STORE R0,t2
LOAD t3,R0
LOAD t2,R1
DIV R1,R0
STORE R0,t2
LOAD t2,R1
STORE R1,t2
LOAD t2,R0
JGT 5,label#11
28
www.jntuworld.com
www.jntuworld.com
CD LAB PROGRAMS
Label#11: OUT t2
JMP t2,label#13
Label#13: STORE t3,99
LOAD 25,R1
STORE R1,t2
LOAD t2,R0
LOAD t3,R1
MUL R1,R0
STORE R0,t3
LOAD t1,R1
STORE R1,t1
LOAD t1,R0
LOAD t3,R1
ADD R1,R0
STORE R0,t4
L D
OUT t4
O R
U W
N T
J
29
www.jntuworld.com