Cs8602 Lab Manual
Cs8602 Lab Manual
LAB MANUAL
(2017 Regulation)
NAME :
REGISTER NO. :
YEAR/ SEM :
III / Sixth
:
SUBJECT CS8602 Compiler Design
Laboratory
AUTONOMOUS
LABORATORY RECORD
BONAFIDE CERTIFICATE
_____________________ _______________________
Head of the Department Lab Course Incharge
Signature of Examiners:
To produce highly qualified and motivated graduates through a rigourous curriculum of theory
and application that develops the ability to solve problems, individually and in teams.
Creating knowledge of fundamental principles and innovative technologies through research
within the core areas of computer science and also in inter- disciplinary topics.
Serving the communities to which we belong at local and national levels, combined with a deep
awareness of our ethical responsibilities to our profession and to society.
To contribute effectively to the important national endeavour to produce quality human resource
in the information technology and related areas for sustainable development of the country’s IT
industry needs.
To advance the state of the art in computer science and engineering by working on cutting edge
research topics, publishing quality research papers and filing enduring patents.
To serve the local and the national community by creating awareness about IT related products
and to impress upon then the importance of knowledge management.
LIST OF EXPERIMENTS
AIM:
INTRODUCTION:
TOKEN
A token is a structure representing a lexeme that explicitly indicates its categorization
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
ALGORITHM:
1. Start the program.
2. Include necessary header files.
11. Also count the numbers of each token that occurs in input file and print it.
PROGRAM :
#include<stdio.h>
#include<ctype.h>
#include<string.h> void
keyw(char *p);
int i=0,id=0,kw=0,num=0,op=0;
char keys[32][10]={"auto","break","case","char","const","continue","default",
"do","double","else","enum","extern","float","for","goto","if","int","long","register","
return","short","signed","sizeof","static","struct","switch","typedef","union",
"unsigned","void","volatile","while"};
main()
{
}
printf("Keywords: %d\nIdentifiers: %d\nOperators: %d\nNumbers:
%d\n",kw,id,op,num);
//getch(); END:
printf("file not found");
}
void keyw(char *p)
{
int k,flag=0; for(k=0;k<=31;k++)
{
if(strcmp(keys[k],p)==0)
{
printf("%s is a keyword\n",p); kw++;
flag=1; break;
}
}
if(flag==0)
{
if(isdigit(p[0]))
{
i=-1;
}
INPUT: (INPUT.C)
#include<stdio.h>
#include<conio.h> void
main()
{
Int a,b,c; a=10;
b=5;
c=a+b;
printf(“The sum is %d”,c);
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:2 IMPLEMENTATION OF LEXICAL ANALYZER USING LEX TOOL
AIM:
INTRODUCTION:
THEORY:
1. Declare the variables which are used for C programs in the declaration section
%{...%}.
2. Include the pattern (regular expression) in the transition rule section %%..%%
3. Write the regular expressions for keywords, identifiers, operators, delimiters and
symbols.
4. In the main function open the file “lexy.txt” in read mode.
5. Then call the yylex() function to scan the input file and display the output.
6. Separate the keyword in the program and display it using lex.
7. Separate the operators of the input program and display it.
8. Print the punctuation marks.
9. Print the constant that are present in input program.
10. Print the identifiers of the input program using lex tool.
PROGRAM: (lexid.l)
%{
#include<stdio.h> int
e,k,c,d,i,s;
%}
%%
include|void|main|int|float|double|scanf|char|printf {printf("keyword"); i++;} [a-z]
[a-zA-Z0-9]* {printf("Identifier"); k++;}
[0-9]* {printf("digit"); e++;}
[+|-|*|/|=]* {printf("operator"); c++;} [;|:|(|)|{|}|"|'|,|\n|\
t]* {printf("delimeter"); d++;} [#|<|>|%]*
{printf("symbols"); s++;}
%%
int main(void)
{
yyin=fopen("lexy.txt","r");
yylex();
printf("\nidentifier %d\n",k);
printf("Symbols %d\n",s);
printf("digits %d\n",e); printf("
Operator %d\n",c); printf("
keywords %d\n",i);
printf("delimeter %d\n",d); return
1;
}
int yywrap()
{
return 1;
}
INPUT:
Lexyi.txt int
a=10;
OUTPUT:
C:/FlexWindow:/EditPlusPortable> lex lexid.l
C:/FlexWindow:/EditPlusPortable> cc lex.yy.c
C:/FlexWindow:/EditPlusPortable> a
Identifier 1
Digit 1
Keyword 1
Operator 1
Delimiter 1
RESULT:
Thus the program for the exercise on lexical analysis using lex has been
successfully executed and output is verified.
EX. NO 3 (a) PROGRAM TO RECOGNIZE A VALID ARITHMETIC EXPRESSION THAT
USESOPERATOR +, - , * AND / USING YACC
AIM:
To write a Yacc program to valid arithmetic expression using Yacc
ALGORITHM:
1. Declare the variables which are used for C programs in the declaration section %
{...%}.
2. Define the tokens, precedence and associativity of operators used in yacc.
3. Include the pattern (Context Free Grammar) in the transition rule section for
validating the expression between %%..%%
4. In main function get the expression from the user for validating it.
5. Call the yyparse() function to parse the given expression and it construct the
LALR parsing table using the grammar defined in transition rule .
6. Then call the yylex() function, it get the current token and store its value in yylval
variable and it is repeated until the value for given expression is computed.
7. Then it validates the expression with constructed LALR parser.
8. Print the expression is VALID if the expression given by user is derived by
the grammar, else print INVALID.
9. Stop the program.
PROGRAM:
%{
#include<ctype.h>
#include<stdlib.h>
#include<string.h> #define
YYSTYPE double
%}
%token num
%left '+' '-'
%left '*' '/'
%%
st: st expr '\n' {printf("VALID");}
|st '\n'
|
|error '\n' {printf("INVALID");}
;
expr: num
|expr '+' expr
|expr '/' expr
%%
main()
{
printf(" ENTER AN EXPRESSION TO VALIDATE");
yyparse();
}
yylex()
{
int ch; while((ch=getchar())==' ');
if(isdigit(ch)|ch=='.')
{
ungetc(ch,stdin);
scanf("%lf",&yylval); return
num;
}
return ch;
}
yyerror(char *s)
{
printf("%S",s);
}
OUTPUT:
RESULT:
Thus the program for validating arithmetic expression was done and executed
successfully.
Ex. No: 3 (b) PROGRAM TO RECOGNIZE A VALID VARIABLE WHICH STARTS
WITH A LETTER FOLLOWED BY ANY NUMBER OF LETTERS OR
DIGITS
AIM :
To write a yacc program to check valid variable followed by letter or digits
ALGORITHM:
1. Declare the variables which are used for C programs in the declaration section
%{...%}.
2. Define the tokens let, dig used in yacc.
3. Include the pattern (Context Free Grammar) in the transition rule section for
validating the variable between %%..%%
4. In main function get the variable from the user for validating it.
5. Call the yyparse() function to parse the given expression and it construct the
LALR parsing table using the grammar defined in transition rule .
6. Then call the yylex() function, it get the current token and store its value in yylval
variable and it is repeated until the value for given variable.
7. Then it validates the variable with constructed LALR parser.
8. Print the variable is “accepted” if the variable given by user is derived by the
grammar, else print “rejected”.
9. Stop the program.
PROGRAM:
%{
#include<stdio.h>
#include<ctype.h>
%}
%token let dig
%%
%%
yylex()
{
}
sad: let recld '\n' {printf("accepted\n"); return 0;}
| let '\n' {printf("accepted\n"); return 0;}
|
|error {yyerror("rejected\n");return 0;}
;
recld: let recld
| dig recld
| let
| dig
;
char ch; while((ch=getchar())==' ');
if(isalpha(ch))
return let; if(isdigit(ch))
return dig; return ch;
yyerror(char *s)
{
}
main()
{
printf("%s",s);
printf("ENTER A variable : "); yyparse();
}
OUTPUT:
C:\Flex Windows\EditPlusPortable>yacc -d valid.y C:\
Flex Windows\EditPlusPortable> cc y.tab.c C:\Flex
Windows\EditPlusPortable> a
A1
accepted 10a
rejected
RESULT:
Thus the program for checking letter followed by letter or digits were done and executed
successfully.
Ex. No: 4 IMPLEMENTATION OF CALCULATOR USING LEX AND YACC
AIM :
To write a yacc program to implement calculator using lex and yacc
ALGORITHM:
1. Declare the variables and header files which are used for C programs in the
declaration section %{...%} of lex and yacc file.
2. Include the pattern (regular expression in lex and CFG in yacc) in the transition rule
section %%..%%
3. Define the tokens, precedence and associativity of operators used in yacc.
4. In main function get the expression from the user for calculation.
5. Call the yyparse() function to parse the given expression and it construct the LALR
parsing table using the grammar defined in transition rule of yacc.
6. Then call the yylex() function, it get the current token and store its value in yylval
variable and it is repeated until the value for given expression is computed.
7. Then it computes the expression with constructed LALR parser.
8. Print the value of expression.
9. Stop the program.
PROGRAM:
Cal.l
%{
%}
#include <stdio.h> #include "y.tab.h" int c;
extern int yylval;
[a-z]{
}
[0-9] {
c = yytext[0]; yylval = c - 'a'; return (LETTER);
c = yytext[0]; yylval = c - '0'; return(DIGIT);
[^a-z0-9\b]{
c = yytext[0];
return(c);
}
Cal.Y
%{
%}
#include <stdio.h> int regs[26];
int base;
%start list
%token DIGIT LETTER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */
main()
{
return(yyparse());
}
yyerror(s) char *s;
{
fprintf(stderr, "%s\n",s);
}
yywrap()
{
return(1);
}
(OR)
%{
#include<stdio.h> int op=0,i;
float a,b;
%}
dig[0-9]+|([0-9]*)"."([0-9]+)
add "+" sub "-" mul"*"
div "/"
pow "^" ln \n
%%
%%
digi()
{
{dig}{digi();}
{add}{op=1;}
{sub}{op=2;}
{mul}{op=3;}
{div}{op=4;}
{pow}{op=5;}
{ln}{printf("\n the result:%f\n\n",a);}
if(op==0) a=atof(yytext); else
{
b=atof(yytext); switch(op)
{
case 1: a=a+b;
break; case 2: a=a-b;
break; case 3: a=a*b;
break; case 4: a=a/b;
break;
}
op=0;
}
}
case 5: for(i=a;b>1;b--)
a=a*i; break;
main(int argv,char *argc[])
{
yylex();
}
yywrap()
{
return 1;
}
OUTPUT:
RESULT:
Thus the program to implement calculator using lex and yacc was done and executed.
Ex.No: 5 IMPLEMENTATION OF THE BACK END OF THE COMPILER
AIM:
INTRODUCTION:
A compiler is a computer program that implements a programming language specification
to “translate” programs, usually as a set of files which constitute the source code written in
source language, into their equivalent machine readable instructions(the target language,
often having a binary form known as object code). This translation process is called
compilation.
BACK END:
Some local optimization
Register allocation
Peep-hole optimization
Code generation
Instruction scheduling
The main phases of the back end include the following:
Analysis: This is the gathering of program information from the intermediate
representation derived from the input; data-flow analysis is used to build use- define
chains, together with dependence analysis, alias analysis, pointer analysis, escape
analysis etc.
Optimization: The intermediate language representation is transformed into
functionally equivalent but faster (or smaller) forms. Popular optimizations are
expansion, dead, constant, propagation, loop transformation, register allocation and
even automatic parallelization.
Code generation: The transformed language is translated into the output language, usually the
native machine language of the system. This involves resource and storage decisions, such as deciding
which variables to fit into registers and memory and the selection and scheduling of appropriate
machine instructions along with their associated modes. Debug data may also need to be generated to
facilitate debugging
ALGORITHM:
PROGRAM:
return 0;
}
OUTPUT:
RESULT:
Thus, the c program for implementing backend of the compiler was done successfully.
Ex. No : 6 IMPLEMENTATION OF SIMPLE CODE OPTIMIZATION
TECHNIQUES
AIM:
To write a C program to eliminate dead code as code optimization
INTRODUCTION:
▪ Optimization should increases the speed of the program and if possible, the program
should demand less number of resources.
▪ Optimization should itself be fast and fast and should not delay the overall compiling
process.
ALGORITHM:
PROGRAM:
else
{
all_var[ptr]=c;
ptr++;
}
}
printf("\n The unused variables are: "); for(i=0;i<=ptr;i++)
{
for(j = i+1; j <= ptr; j++)
{
for(j = i+1; j <= ptr; j++)
{
all_var[ptr]=c; ptr++;
OUTPUT:
b is unused variable
RESULT:
Thus the program for code optimization was implemented and output was obtained.
Ex. No : 7 GENERATE THREE ADDRESS CODE FOR A SIMPLE PROGRAM
USING LEX AND YACC
AIM :
To write a yacc program to Generate Three Address Code using lex and yacc
ALGORITHM:
1. Declare the variables and header files which are used for C programs in the declaration
section %{...%} of lex and yacc file.
2. Include the pattern (regular expression in lex and CFG in yacc) in the transition rule
section %%..%%
3. Define the tokens, precedence and associativity of operators used in yacc.
4. In main function get the expression from the user for calculation.
5. Call the yyparse() function to parse the given expression and it construct the LALR
parsing table using the grammar defined in transition rule of yacc.
6. Then call the yylex() function, it get the current token and store its value in yylval
variable and it is repeated until the value for given expression is computed.
7. Then it computes the expression with constructed LALR parser.
8. Print the value of expression.
9. Stop the program.
PROGRAM:
Three.l
%{
#include #include
#include “y.tab.h”
%}
%%
[0-9]+ {yylval.dval=atoi(yytext);return NUM;} [t];
n return 0;
. {return yytext[0];}
%%
Three.y
%{
#include
int yylex(void); char p=’A’-1;
%}
%union
{
char dval;
}
%token NUM
%left ‘+’ ‘-‘
%left ‘*’ ‘/’
%nonassoc UMINUS
%type S
%type E
%%
S : E {printf(” x = %cn”,$$);}
;
E : NUM {}
| E ‘+’ E {p++;printf(“n %c = %c + %c “,p,$1,$3);$$=p;}
| E ‘-‘ E {p++;printf(“n %c = %c – %c “,p,$1,$3);$$=p;}
| E ‘*’ E {p++;printf(“n %c = %c * %c “,p,$1,$3);$$=p;}
| E ‘/’ E {p++;printf(“n %c = %c / %c “,p,$1,$3);$$=p;}
| ‘(‘E’)’ {$$=p;}
| ‘-‘ E %prec UMINUS {p++;printf(“n %c = -%c “,p,$2);$$=p;}
;
%%
OUTPUT:
[a40@localhost ~]$ lex threee.l [a40@localhost ~]$ yacc -d threee.y [a40@localhost ~]$ cc
lex.yy.c y.tab.c -ll [a40@localhost ~]$ ./a.out
Enter Expression x => 1+2-3*3/1+4*5 A = 1+2
B = 3*3 C = B/1 D = A-C E = 4*5 F = D+E X = F
[a40@localhost ~]$ ./a.out
Enter Expression x => 1+2*(3+4)/5 A = 3+4
B = 2*A C = B/5
D = 1+C X = D
[a40@localhost ~]$ ./a.out
Enter Expression x => 1+2*(-3+-6/1)*3 A = -3
B = -6 C = B/1
D = A+C E = 2*D F = E*3 G = 1+F X = G
RESULT:
Thus the program for code optimization was implemented and output was obtained.