Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Compiler Lab Manual

You are on page 1of 59

THE KAVERY ENGINEERING COLLEGE,

Mecheri, Salem

NAME OF THE LABORATORY :

CS6612/ COMPLIER LABORATORY

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


SYLLABUS
The student should be made to:
Be exposed to compiler writing tools.
Learn to implement the different Phases of compiler
Be familiar with control flow and data flow analysis
Learn simple optimization techniques
LIST OF EXPERIMENTS:
1. Implementation of Symbol Table
2. Develop a lexical analyzer to recognize a few patterns in C. (Ex. identifiers, constants,
comments, operators etc.)
3. Implementation of Lexical Analyzer using Lex Tool
4. Generate YACC specification for a few syntactic categories.
a) Program to recognize a valid arithmetic expression that usesoperator +, - , * and /.
b) Program to recognize a valid variable which starts with a letter followed by any number of
letters or digits.
d)Implementation of Calculator using LEX and YACC
5. Convert the BNF rules into Yacc form and write code to generate Abstract Syntax Tree.
6. Implement type checking
7. Implement control flow analysis and Data flow Analysis
8. Implement any one storage allocation strategies(Heap,Stack,Static)
9. Construction of DAG
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.
11. Implementation of Simple Code Optimization Techniques (Constant Folding., etc.)

TOTAL: 45 PERIODS
OUTCOMES:
At the end of the course, the student should be able to
Implement the different Phases of compiler using tools
Analyze the control flow and data flow of a typical program
Optimize a given program
Generate an assembly language program equivalent to a source language program

LIST OF EQUIPMENT FOR A BATCH OF 30 STUDENTS:


Standalone desktops with C / C++ compiler and Compiler writing tools 30 Nos.
(or)
Server with C / C++ compiler and Compiler writing tools supporting 30 terminals or more.
LEX and YACC

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory
INDEX

Page Marks
S. No. Date Name of the Experiment Remarks
No. Awarded

1 Implementation of Symbol Table

Develop a lexical analyzer to recognize a


2
few patterns in C

Implementation of Lexical Analyzer using


3
Lex Tool

Generate YACC specification:


4. a Program to recognize a valid arithmetic
expression that usesoperator +, - , * and /
Generate YACC specification:
Program to recognize a valid variable
4. b
which starts with a letterfollowed by any
number of letters or digits
Generate YACC specification:
4. c Implementation of Calculator using LEX
and YACC
Convert the BNF rules into Yacc form and
5 write code to generate Abstract Syntax
Tree

6 Implement type checking

Implement control flow analysis and Data


7
flow Analysis

Implement any one storage allocation


8
strategies(Heap,Stack,Static)

9 Construction of DAG

Implement: Three address code and


10
produces the 8086 assembly language
Implementation of Simple Code
11 Optimization Techniques (Constant
Folding., etc.)

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


VIVA VOCE

Page Marks
S. No. Date Name of the Experiment Remarks
No. Awarded

1 Implementation of Symbol Table

Develop a lexical analyzer to recognize a


2
few patterns in C

Implementation of Lexical Analyzer using


3
Lex Tool

Generate YACC specification:


4. a Program to recognize a valid arithmetic
expression that usesoperator +, - , * and /
Generate YACC specification:
Program to recognize a valid variable
4. b
which starts with a letterfollowed by any
number of letters or digits
Generate YACC specification:
4. c Implementation of Calculator using LEX
and YACC
Convert the BNF rules into Yacc form and
5 write code to generate Abstract Syntax
Tree

6 Implement type checking

Implement control flow analysis and Data


7
flow Analysis

Implement any one storage allocation


8
strategies(Heap,Stack,Static)

9 Construction of DAG

Implement: Three address code and


10
produces the 8086 assembly language
Implementation of Simple Code
11 Optimization Techniques (Constant
Folding., etc.)

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 1
Implementation of Symbol Table
Date:

Aim:
To implement Symbol Table using C program.
Description:
Symbol table management:
Symbol table is a data structure containing the record of each identifier, with fields
for the attributes of the identifier. The data structure allows us to find the record for each
identifier quickly and store or retrieve data from that record quickly. When
the lexical analyzer detects an identifier in the source program, the identifier is entered into
symbol table. The remaining phases enter information about identifiers in to the symbol table.
Coding:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#include<alloc.h>
#include<math.h>
void main()
{
int i=0,j=0,x=0,n,flag=0;
void *p,*add[15];
char ch,c,srch,b[15],d[15];
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("symbol table");
printf("\nsymbol \taddr \ttype\n");
while(j<=n)
{ c=b[j];

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


if(isalpha(toascii(c)))
{
if(j==n)
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("%c \t %d \t Identifier \n",c,p);
}
else
{
ch=b[j+1];
if(ch=='+'||ch=='-'||ch=='*'||ch=='=')
{
p=malloc(c);
add[x]=p;
d[x]=c;
printf("%c \t %d \t Identifier \n",c,p);
x++;}}}j++;}
printf("The symbol to be searched");
srch=getch();
for(i=0;i<=x;i++)
{
if (srch==d[i])
{
printf("\n symbol found");
printf("%c %s %d \n",srch,"@address",add[i]);
flag=1;
}
}
if(flag==0)
printf("\n symbol not found");
getch();
}

OUTPUT:

Expression terminated by $: a+b*c$


Given Expression : a+b*c
Symbol table
Symbol Address Type
a 1904 Identifier
b 2006 Identifier
c 2108 Identifier
The symbol to be searched a
Symbol found a @ address 1904

Result:
Thus the symbol table using C program was implemented successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 2
Develop a lexical analyzer to recognize a few patterns in C
Date:

Aim:
To implement Lexical Analysis using C.
Description:

In compiler, lexical analysis is also called linear analysis or scanning. In lexical analysis the
stream of characters making up the source program is read from left to right and grouped into tokens
that are sequences of characters having a collective meaning.
LEX:
LEX helps write programs whose control flow is directed by instances of regular expressions
in the input stream. It is well suited for editor-script type transformations and for segmenting input in
preparation for a parsing routine.
LEX is a program generator designed for Lexical processing of character input streams. It
accepts a high-level, problem oriented specification for character string matching, and produces a
program in a general purpose language which recognizes regular expressions. The regular expressions
are specified by the user in the source specifications given to LEX. The LEX written code recognizes
these expressions in an input stream and partitions the input stream into strings matching the
expressions. At the boundaries between strings program sections provided by the user are executed.
The LEX source file associates the regular expressions and the program fragments. As each
expression appears in the input to the program written by LEX, the corresponding fragment is
executed
The user supplies the additional code beyond expression matching needed to complete his
tasks, possibly including code written by other generators. The program that recognizes the
expressions is generated in the general purpose programming language employed for the user's
program fragments. Thus, a high level expression language is provided to write the string expressions
to be matched while the user's freedom to write actions is unimpaired. This avoids forcing the user
who wishes to use a string manipulation language for input analysis to write processing programs in
the same and often inappropriate string handling language
LEX is not a complete language, but rather a generator representing a new language feature
which can be added to different programming languages, called ``host languages.'' Just as general
purpose languages can produce code to run on different computer hardware, LEX can write code in
different host languages
LEX turns the user's expressions and actions (called source in this memo) into the host
general-purpose language; the generated program is named yyLEX. The yyLEX program will
recognize expressions in a stream (called input in this memo) and perform the specified actions for
each expression as it is detected. See Figure 1.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


LEX Source Program lex.yy.c
LEX Compiler

lex.yy.c C Compiler a.out

Input Stream Sequence of Tokens


a.out

LEX Source:
The general format of LEX source is:
{definitions}
%%
{rules}
%%
{user subroutines}
where the definitions and the user subroutines are often omitted. The second %% is optional, but the
first is required to mark the beginning of the rules. The absolute minimum LEX program is thus (no
definitions, no rules) which translates into a program which copies the input to the output unchanged.

CODING:

Program Name:

#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);
}

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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");
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);

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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
{
str[k]='\0';
keyword(str);
k=0;
}
}

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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);
}
output:
Enter the C program
a+b*c
Ctrl-D
The no’s in the program are:
The keywords and identifiers are:
a is an identifier and terminal
b is an identifier and terminal
c is an identifier and terminal
Special characters are:
+*
Total no. of lines are: 1

Result:

Thus the Lexical Analysis using C program was implemented successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 3
Implementation of Lexical Analyzer using Lex Tool
Date:

Aim:
Aim:
To implement Lexical Analysis using Lex Tool.
Description:

In compiler, lexical analysis is also called linear analysis or scanning. In lexical analysis the
stream of characters making up the source program is read from left to right and grouped into tokens
that are sequences of characters having a collective meaning.
LEX:
LEX helps write programs whose control flow is directed by instances of regular expressions
in the input stream. It is well suited for editor-script type transformations and for segmenting input in
preparation for a parsing routine.
LEX is a program generator designed for Lexical processing of character input streams. It
accepts a high-level, problem oriented specification for character string matching, and produces a
program in a general purpose language which recognizes regular expressions. The regular expressions
are specified by the user in the source specifications given to LEX. The LEX written code recognizes
these expressions in an input stream and partitions the input stream into strings matching the
expressions. At the boundaries between strings program sections provided by the user are executed.
The LEX source file associates the regular expressions and the program fragments. As each
expression appears in the input to the program written by LEX, the corresponding fragment is
executed
The user supplies the additional code beyond expression matching needed to complete his
tasks, possibly including code written by other generators. The program that recognizes the
expressions is generated in the general purpose programming language employed for the user's
program fragments. Thus, a high level expression language is provided to write the string expressions
to be matched while the user's freedom to write actions is unimpaired. This avoids forcing the user
who wishes to use a string manipulation language for input analysis to write processing programs in
the same and often inappropriate string handling language
LEX is not a complete language, but rather a generator representing a new language feature
which can be added to different programming languages, called ``host languages.'' Just as general
purpose languages can produce code to run on different computer hardware, LEX can write code in
different host languages
LEX turns the user's expressions and actions (called source in this memo) into the host
general-purpose language; the generated program is named yyLEX. The yyLEX program will

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


recognize expressions in a stream (called input in this memo) and perform the specified actions for
each expression as it is detected. See Figure 1.

LEX Source Program lex.yy.c


LEX Compiler

lex.yy.c C Compiler a.out

Input Stream Sequence of Tokens


a.out

LEX Source:
The general format of LEX source is:
{definitions}
%%
{rules}
%%
{user subroutines}
where the definitions and the user subroutines are often omitted. The second %% is optional, but the
first is required to mark the beginning of the rules. The absolute minimum LEX program is thus (no
definitions, no rules) which translates into a program which copies the input to the output unchanged.

CODING:

ALGORITHM:

Step1: Declare all the variables, constants and regular definitions in the declaration
Section

Step2: Define the patterns and respective actions in the rule section

Step3: Patterns are regular expression and the actions are program fragments.

Step4: In the main function, yylex() function is used to place a call to rule section to
produce necessary tokens.

Step5: It uses yytext-a character array to print the tokens matching the patterns.

Step6: yyin() is a input function used to open a fil in read mode.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Step7: yyout() is a output function is used to write the content into a file.

Step8: The necessary output for each program is displayed.

Program Name:

/* program name is lexp.l */


%{
/* program to recognize a c program */
int COMMENT=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
int |
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/
"*/" {COMMENT = 0;}
/* printf("\n\n\t%s is a COMMENT\n",yytext);}*/
{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");
return 0;
} int yywrap()

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


{
return 0;
}
Input:
$vi var.c
#include<stdio.h>
main()
{
int a,b;
}
Output:
$lex lex.l
$cc lex.yy.c
$./a.out var.c
#include<stdio.h> is a PREPROCESSOR DIRECTIVE
FUNCTION
main (
)
BLOCK BEGINS
int is a KEYWORD
a IDENTIFIER
b IDENTIFIER
BLOCK ENDS

Result:

Thus the symbol table using C program was implemented successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 4. A Generate YACC specification:

Program to recognize a valid arithmetic expression that usesoperator +, - , *


Date: and /

Aim:

To implement Yacc programs.

Description:

YACC
Theory:
Yacc stands for "yet another compiler-compiler," reflecting the popularity of parser
generators in the early 1970's when the first version of Yacc was created by S. C. Johnson. Yacc is
available as a command on the UNIX system, and has been used to help implement hundreds of
compilers.
Structure of a Yacc Grammar
A yacc grammar consists of three sections: the definition section, the rules section, and the user
subroutines section.
... definition section ...
%%
... rules section ...
%%
... user subroutines section ...
The sections are separated by lines consisting of two percent signs. The first two sections are required,
although a section may be empty. The third section and the preceding "%%" line may be omitted.

CODING:

Program Name:
1. Write a YACC Program to check whether given string a^nb^n is accepted by
the grammar.

%{
#include<stdio.h>
%}

%token A B

%%
S : ASB
| AB
|
;
%%

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


yyerror()
{
Printf(“\n the string does not belong to the grammar”);
}

int yylex()
{
char ch;
ch=getchar();
if (ch==’a’)
return A;
else if (ch==’b’)
return B;
else if(ch==’\n’)
return 0;
else return ch;
}

int main()
{
Printf(“enter the expression \n”);
yyparse();
Printf(“\n string accepted by grammar”);
Return 0;
}

2. Write a YACC program to check the validity of an arithmetic expression.

%{
#include<stdio.h>
#include<stdlib.h>
%}
%token ID
%left '+','-'
%left '*','/'

%%
E:E'+'E { printf("valid expression);}
| E'-'E { printf("valid expression);}
| E'/'E { printf("valid expression);}
| E'*'E { printf("valid expression);}
| ID
;
%%
int yylex()
{
Char ch;

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ch=getchar();
if(isalnum(ch))
return ID;
else if(ch==’\n’)
return 0;

else return ch;

yyerror()

Printf(“\n invalid expression”);

int main()
{
printf("Enter the expression");
yyparse();

Output:

Result:

Thus the Program for Yacc was successfully implemented.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Generate YACC specification:
Ex. No: 4. B
Program to recognize a valid variable which starts with a letterfollowed by any
Date: number of letters or digits

Aim:

To implement Syntax Analysis using YACC.

Description:

Syntax analysis
It is also called as Hierarchical analysis or parsing. It involves grouping the tokens of the
source program into grammatical phrases that are used by the compiler to synthesize output. Usually,
a parse tree represents the grammatical phrases of the sourse program.
CODING:

ALGORITHM 1:

Step 1: Start the program

Step 2: In the LEX tool include the regular definition

Step 3: When the regular definition morning is given return MOR token

Step 4: When newline is given return NEWLINE token

Step 5: In the YACC program when the yyparse() is called it will execute the yylex()
function in turn to get the necessary token (i.e) MOR and NEWLINE

Step 6: When “morning” is keyed it will ask for the name, prints “successful execution of

program”

Step 7: If any other input is given it will print error.

Step 8: Stop the program

Program Name:
RETURN NEWLINE AND TOKEN

new.y:

%{
#include<stdio.h>

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


#define YYSTYPE double
%}
%token MOR NEWLINE
%%
msg:MOR {char name[20];
printf ("\nMay I know your name please..");
scanf("%s",name);
printf ("\n\nGood Morning Mr/Ms %s",name);
}
n1
n1: NEWLINE {printf("\nEnd of the successful execution of the program\n");
return;
}
%%
int main()
{
return yyparse();
}
void yyerror()
{

printf("\nerror...........");
printf("\nPlease enter valid input(morning)");
}
int yywrap()
{
return 1;
}

jj.l:
%{
#include<stdio.h>
#include"y.tab.h"
%}
%%
printf(“Type morning:”)
"morning" {return MOR;}
[\n] {return NEWLINE;}
[.] { }
%%

y.tab.h:

#ifndef YYERRCODE
#define YYERRCODE 256
#endif
#define MOR 257

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


#define NEWLINE 258

OUTPUT:

[student@localhost ~]$ vi new.y


[student@localhost ~]$ vi jj.l
[student@localhost ~]$ vi y.tab.h
[student@localhost ~]$ lex jj.l

[student@localhost ~]$ yacc new.y


[student@localhost ~]$ cc y.tab.c lex.yy.c
[student@localhost ~]$ ./a.out

Type morning:

morning

May I know your name please..Wilson


morning Mr/Ms Wilson

Result:

Thus the Program to recognize a valid variable which starts with a letterfollowed by any
number of letters or digits was implemented successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 4.c Generate YACC specification:

Date: Implementation of Calculator using LEX and YACC

Aim:

To implement calculator using LEX and YACC.

ALGORITHM 2:

Step 1: Start the program

Step 2: Declare the necessary grammar production in the rule section.

Step 3: In the procedure section, using yylex() the token number manipulation is returned to
the

parser.

Step 4: When the yyparse() is called it will do the necessary calculation, also it will get
token

number whenever applicable.

Step 5: The calculation is performed and the result is displayed.

Step 6: Stop the program

CODING:

Program Name:

j.y

%{
#include<stdio.h>
#include<ctype.h>
#define YYSTYPE double
%}
%token NUMBER
%left '+''-'
%left '*''/'
%%
list:list '\n'

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


list:expr'\n' {printf("%lf",$$);}
expr:NUMBER {}

|expr '+' expr {$$=$1+$3;}


|expr '-' expr {$$=$1-$3;}
|expr '*' expr {$$=$1*$3;}
|expr '/' expr
{
if($3==0)
{
printf("\ndivide by 0 exception\n");
exit(0);
}
else
{$$=$1/$3;}
}
|'('expr')' {$$=$2;}
%%
#include<stdio.h>
#include<ctype.h>
//#include"y.tab.h"
main()
{
yyparse();
}
yyerror()
{}
yylex()
{
int c;
while((c=getchar())==' '||c=='t')
if(c==EOF)
return(0);
if(c=='.'||isdigit(c))
{
ungetc(c,stdin);
scanf("%lf",&yylval);
return NUMBER;
}
return c;
}
int yywrap()
{
return 1;
}

OUTPUT:

[student@localhost ~]$ vi j.y


[student@localhost ~]$ yacc j.y
[student@localhost ~]$ cc y.tab.c

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


[student@localhost ~]$ ./a.out
Multiplication:
5*5
25.000000
[student@localhost ~]$ ./a.out
Addition:
5+5
10.000000

[student@localhost ~]$ ./a.out


Subtraction:
50-25
25.000000

[student@localhost ~]$ ./a.out


Division:
15/3
5.000000
[student@localhost ~]$ ./a.out
Division:

34/0

divide by 0 exception

RESULT:

Thus a YACC program to return the NEWLINE & MORNING token and a program
to perform calculator is executed and verified successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 5 Convert the BNF rules into Yacc form and write code to generate Abstract
Syntax Tree
Date:

Aim:

To implement the Shift Reduce Parsing Algorithm & LR Parsing Table.

Description:
LR Parser:
This is bottom –Up syntax analysis technique that can be used to parse a class of CFGs. LR
Parser is actually called LR (K) parsing where,
L – Left to right scanning
R – rightmost derivation
K – Number of input symbols of look ahead that are used in making parsing decisions.
(k is omitted  it is 1)
• LR parsing is attractive because:
– LR parsing is most general non-backtracking shift-reduce parsing, yet it is still
efficient.
– The class of grammars that can be parsed using LR methods is a proper superset of
the class of grammars that can be parsed with predictive parsers.
– LL(1)-Grammars  LR(1)-Grammars
– An LR-parser can detect a syntactic error as soon as it is possible to do so a left-to-
right scan of the input.
Shift-Reduce Parsing:
 Shift-reduce parsing is a method for syntax analysis that constructs the parse
tree on seeing an input string beginning at the leaves and working towards the
root.
 At each step it attempts to reduce a substring from the input by replacing it
with the right side of a grammar production, thus attempting to reach the start
symbol of the grammar.
 At the end of the operation of the shift-reduce parser there can be traced in
reverse the rightmost derivation of the input string according to the grammar.

CODING:

Program Name:
<int.l>
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>
int LineNo=1;
%}

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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.y>
%{
#include<string.h>
#include<stdio.h>
struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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
;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


;
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 {

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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{
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");

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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;
}
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);

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


}
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()

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


{
printf("\n Error on line no:%d",LineNo);
}
Input:
$vi test.c
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:
$lex int.l
$yacc –d int.y
$gcc lex.yy.c y.tab.c –ll –lm
$./a.out test.c

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


OUTPUT:

Result:

Thus the BNF rules into Yacc form and Abstract Syntax Tree was generated.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 6
Implement type checking
Date:

Aim:

Implement a type checker using C program.

Description:

The purpose of types

To define what the program should do.

 e.g. read an array of integers and return a double

To guarantee that the program is meaningful.

 that it does not add a string to an integer


 that variables are declared before they are used

To document the programmer's intentions.

 better than comments, which are not checked by the compiler

To optimize the use of hardware.

 reserve the minimal amount of memory, but not more


 use the most appropriate machine instructions

What belongs to type checking

Depending on language, the type checker can prevent

 application of a function to wrong number of arguments,


 application of integer functions to floats,
 use of undeclared variables in expressions,
 functions that do not return values,
 division by zero
 array indices out of bounds,
 nonterminating recursion,
 sorting algorithms that don't sort...

Languages differ greatly in how strict their static semantics is: none of the things above is
checked by all programming languages!

In general, the more there is static checking in the compiler, the less need there is for manual
debugging.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Description formats for different compiler phases

These formats are independent of implementation language.

 Lexer: regular expressions


 Parser: BNF grammars
 Type checker: typing rules
 Interpreter: operational semantic rules
 Code generator: compilation schemes

CODING:

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


OUTPUT

Result:

Thus the implementation of type checking using C is successfully implemented.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 7
Implement control flow analysis and Data flow Analysis
Date:

Aim:

To Construct Non-Deterministic Finite Automata from a given Regular Expression


and Construct a minimized Deterministic Finite Automata (DFA) from a given
Regular Expression.
Description:
Thompson's Construction Algorithm
Input :A Regular expression ‘r’ over an alphabet
Output :An NFA ‘N’ accepting L(r)
Method :
1) First phase ‘r’ in to it’s constituent sub expressions.
2) Using rules (1) {BASIC RULES}, construct NFA for basic symbols.
3) Using rules (2) {INDUCTIVE RULE}, obtain NFA for regular expression.
4) Each NFA produced at each step posses some properties.
(i) Exactly one final state.
(ii) No edge enters start state.
(iii) No edge leaves final state.
Basic rules :
(1) Building states and transitions of partial NFA for symbols

st art 
1 2

st art
1
a 2

(2)
(a) Building states and transitions of partial NFA for unions

a
2 3
 
st art
1 6
 b 
4 5

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


(b) Building states and transitions of partial NFA for concatenations

start a b
1 2 3
(c) Building states and transitions of partial NFA for closures


st art  a 
1 2 3 4

Description:
Input : A Regular expression ‘r’
Output : An DFA that recognizes L(r).
Method:
1) Construct an syntax tree for the augmented regular expression (r)#, where # is a
unique end marker appended to (r).
2) Construct the functions Null able, first pos, Laptops and follow-on by making
depth- first traversals of T.
3) Construct States, the set of states of D, the Duran the transition table of D by the
following procedure.
4) The start state of D is firstpos(root) and the accepting states are all those
containing the position associated with the end marker #.

Algorithm:

ALGORITHM:

Step1: Start the program.


Step2: Declare the necessary variables. Use the looping statement to check different
conditions for the input.
Step3: Enter the regular expression with the combination of a, b, *, /. Ex. aba, b/a, aba*b
etc.
Step4: Find a match with the ‘if’ conditions, then process the respective regular
expression.

Step5: Print the result.

Step6: Stop the program.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


PROGRAM:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char reg[20];
int q[20][3],i,j,len,a,b;
for(a=0;a<20;a++)
{
for(b=0;b<3;b++)
{
q[a][b]=0;
}}
printf("Regular expression :\n");
scanf("%s",reg);
len=strlen(reg);
i=0;
j=1;
while(i<len)
{
if(reg[i]=='a' & reg[i+1]!='/' & reg[i+1]!='*')
{
q[j][0]=j+1;
j++;
}
if(reg[i]=='b' & reg[i+1]!='/' & reg[i+1]!='*')
{
q[j][1]=j+1;
j++;
}
if(reg[i]=='e' & reg[i+1]!='/' & reg[i+1]!='*')
{
q[j][2]=j+1;
j++;
}
if(reg[i]=='a' & reg[i+1]=='/' & reg[i+2]=='b')
{
q[j][2]=((j+1)*10)+(j+3);
j++;
q[j][0]=j+1;
j++;
q[j][2]=j+3;
j++;
q[j][2]=j+1;
j++;
i=i+2;
}
if(reg[i]=='a'& reg[i+1]=='*')
{

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


q[j][2]=((j+1)*10)+(j+3);
j++;
q[j][0]=j+1;
j++;
q[j][2]=((j+1)*10)+(j-1);
j++;
q[j][2]=((j+1)*10)+(j-1);
j++;
}
if(reg[i]==')' & reg[i+1]=='*')
{
q[0][2]=((j+1)*10)+1;
q[j][2]=((j+1)*10)+1;
j++;
}
i++;
}
printf("Transition function\n");
for(i=0;i<=j;i++)
{
if(q[i][0]!=0)
printf("\nq[%d,a]->%d",i,q[i][0]);
if(q[i][1]!=0)
printf("\nq[%d,b]->%d",i,q[i][1]);
if(q[i][2]!=0)
{
if(q[i][2]<10)
printf("\nq[%d,e]->%d",i,q[i][2]);
else
printf("\nq[%d,e]->%d&%d",i,q[i][2]/10,q[i][2]%10);
}
}
return;
}

OUTPUT:

[student@localhost~] vi stmt.l

(i)Regular expression:

aba*a

Transition function

q[1,a]->2

q[2,b]->3

q[3,e]->4&6

q[4,a]->5

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


q[5,e]->6&4

q[6,e]->7&5

q[7,a]->8

(ii)Regular expression:

b/a

Transition function

q[1,e]->2&4

q[2,b]->3

q[3,e]->6

q[4,a]->5

q[5,e]->6

(iii)Regular expression:

abab

Transition function

q[1,a]->2

q[2,b]->3

q[3,a]->4

q[4,b]->5

RESULT:

Thus the C program to construct NFA from a regular expression is executed and
verified successfully.

AIM:
To write a C program to construct a DFA from a regular expression.

ALGORITHM:

Step1: Start the program.


Step2: Declare the necessary variables. Use the looping statement to check different
condition for the input.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Step3: Enter the regular expression with the combination of a, b,*, +. Ex. a+b, b*a, aba
etc.
Step4: Find a match with the ‘if’ conditions, and then processes the respective regular
expression.
Step5: Print the result.
Step6: Stop the program.

PROGRAM:
#include<stdio.h>
#include<string.h>
int main()
{
int t,i=0,j=0;
char ch[10],l[10],r[10];
printf("\nRegular expression to DFA \n");
printf("\nEnter the regular expression :");
scanf("%s",ch);
t=strlen(ch);
while(i<=t)
{
if(ch[i]=='a'||ch[i]=='b')
{
l[j]=ch[i];
j++;
}
else if(ch[i]=='*')
{
r[j-1]=ch[i-1];
l[j-1]='\0';
j--;
}
else if(ch[i]=='+')
{
r[j]=ch[i-1];
}
i++;
}
printf("\nTransition table for DFA\n");
printf("\nStates\ta\tb\n");
for(i=0;i<=j;i++)
{
if(r[i]=='a')
{
if(l[i]=='a')
printf("\n %d\t%d\t%d",i,i,i+1);
else if(l[i]=='b')
printf("\n %d\t%d\t%d",i,i,i+1);
else
printf("\n %d\t %d",i,i);
}
else if(r[i]=='b')
{

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


if(l[i]=='b')
printf("\n %d\t\t%d,%d",i,i,i+1);
else if(l[i]=='a')
printf("\n %d\t %d\t%d",i,i+1,i);
else
printf("\n %d\t\t%d",i,i);
}
else
{
if(l[i]=='a')
printf("\n %d\t %d",i,i+1);
else if(l[i]=='b')
printf("\n %d\t\t%d",i,i+1);
else
printf("\n %d\t-\t-",i);
}
}
}

OUTPUT:
(i)Regular expression to DFA
Enter the regular expression: a+b
Transition table for DFA
States a b
0 1
1 1 2
2 - -

(ii)Regular expression to DFA


Enter the regular expression: b*a
Transition table for DFA
States a b
0 1 0
1 - -

RESULT:

Thus the C program to construct DFA from a regular expression is executed and
verified successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 8
Implement any one storage allocation strategies(Heap,Stack,Static)
Date:

Aim:

To implement a storage allocation of a compiler using c program.

Description:

 Statically allocated names are bound to storage at compile time.


 Storage bindings of statically allocated names never change, so even if a name is local
to a procedure, its name is always bound to the same storage.
 The compiler uses the type of a name (retrieved from the symbol table) to determine
storage size required.
 The required number of bytes (possibly aligned) is set aside for the name.
 The address of the storage is fixed at compile time.
 Storage is organized as a stack.
 Activation records are pushed and popped.
 Locals and parameters are contained in the activation records for the call.
 This means locals are bound to fresh storage on every call.
 If we have a stack growing downwards, we just need a stack_top pointer.
 To allocate a new activation record, we just increase stack_top.
 To deallocate an existing activation record, we just decrease stack_top.

Heap allocation:

 Some languages do not have tree-structured allocations.


 In these cases, activations have to be allocated on the heap.
 This allows strange situations, like callee activations that live longer than their callers’
activations.
 This is not common.

CODING:

Program Name:
INSERTION
PUSH(item)
1. If (item = max of stack)
Print “overflow”
Return
2. top = top + 1
3. stack[top] = item
4. Return
DELETION
POP(item)
1. If (top = - 1)

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Print “underflow”
Return
2. Item = stack[top]
3. top = top - 1
4. Return
DISPLAY
1. If top = - 1
Print “underflow”
2. repeat step 3 for i = top to i >= 0
3. Print stack[i]
4. Return

#include<stdio.h>
#include<conio.h>
#define MAXSIZE 10
void push();
int pop();
void traverse();
int stack[MAXSIZE];
int Top=-1;
void main()
{
int choice;
char ch;
do
{
clrscr();
printf("\n1. PUSH ");
printf("\n2. POP ");
printf("\n3. TRAVERSE ");
printf("\nEnter your choice");
scanf("%d",&choice);
switch(choice)
{
case 1: push();
break;
case 2: printf("\nThe deleted element is %d",pop());
break;
case 3: traverse();
break;
default: printf("\nYou Entered Wrong Choice");
}
printf("\nDo You Wish To Continue (Y/N)");
fflush(stdin);
scanf("%c",&ch);
}
while(ch=='Y' || ch=='y');
}
void push()
{
int item;
if(Top == MAXSIZE - 1)
{
printf("\nThe Stack Is Full");
getch();
exit(0);
}
else

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


{
printf("Enter the element to be inserted");
scanf("%d",&item);
Top= Top+1;
stack[Top] = item;
}
}
int pop()
{
int item;
if(Top == -1)
{
printf("The stack is Empty");
getch();
exit(0);
}
else
{
item = stack[Top];
Top = Top-1;
}
return(item);
}
void traverse()
{
int i;
if(Top == -1)
{
printf("The Stack is Empty");
getch();
exit(0);
}
else
{
for(i=Top;i>=0;i--)
{
printf("Traverse the element");
printf("\n%d",stack[i]);
}
}
}

Output:

1.Push
2.POP
3.traverse
Enter the choice: 1
Enter the element to be inserted:
Result:

Thus the stack operation implemented using C was successfully completed.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 9
Construction of DAG
Date:

Aim:

To construct a DAG of compiler using C.

Description:

A directed acyclic graph (DAG!) is a directed graph that contains no cycles. A rooted tree is
a special kind of DAG and a DAG is a special kind of directed graph. For example, a DAG
may be used to represent common subexpressions in an optimising compiler.

+ +
. . . .
. . . .
* () *<---| ()
.. . . .. | . .
. . . . . . | . |
a b f * a b | f |
.. ^ v
. . | |
a b |--<----

Tree DAG

expression: a*b+f(a*b)

Example of Common Subexpression.


The common subexpression a*b need only be compiled once but its value can be used twice.

A DAG can be used to represent prerequisites in a university course, constraints on


operations to be carried out in building construction, in fact an arbitrary partial-order `<'. An
edge is drawn from a to b whenever a<b. A partial order `<' satisfies:

(i) transitivity, a<b and b<c implies a<c

(ii) non-reflexive, not(a < a)

Coding:

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory
Result:

The Construction of DAG was implemented successfully.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Ex. No: 10 Implement: Three address code and produces the 8086 assembly language

Aim:

To Generate Code for a given Intermediate Code.

Description:
Intermediate codes are machine independent codes, but they are close to machine instructions.
 The given program in a source language is converted to an equivalent program in an
intermediate language by the intermediate code generator.
 Intermediate language can be many different languages, and the designer of the compiler
decides this intermediate language.
o syntax trees can be used as an intermediate language.
o postfix notation can be used as an intermediate language.
o three-address code (Quadruples) can be used as an intermediate language
 we will use quadruples to discuss intermediate code generation
 Quadruples are close to machine instructions, but they are not actual machine
instructions.

ALGORITHM:

Step1: Start the program

Step2: Initialize the code, input and the code generator functions.

Step3: Enter your three address code statements and # to terminate.

Step4: The intermediate form of expression generates the code in assembler language

Step5: The ADD, SUB, MUL, DIV are the results obtained for +,-,*,/. The MOV
operation is also used to process with registers.

Step6: Print the code for the expression using the code generator function.

Step7. Stop the program.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


PROGRAM:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

char optr[4]={'+','-','*','/'};

char code[5][4]={{"ADD"},{"SUB"},{"MUL"},{"DIV"}};

char input[20][6];

void codegen();

void getip();

void assemble(char *pos,int j);

int main()

getip();

codegen();

void getip()

int i;

printf("Enter ur 3 address code stmtz & # to terminate :\n");

for(i=0;;i++)

scanf("%s",input[i]);

if(strcmp("#",input[i])==0)

break;

}}

void codegen()

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


int i,j,flag=0;

for(i=0;strcmp("#",input[i])!=0;i++)

for(j=0;j<5;j++)

flag=0;

if(input[i][3]=='\0')

printf("MOV %c,%c\n",input[i][2],input[i][0]);

flag=1;

break;

else

if(input[i][3]==optr[j])

assemble(input[i],j);

flag=1;

break;

}}}

if(flag==0)

printf("ERROR!!!!!!!!\n");

exit(0);

void assemble(char *pos,int j)

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


{

int index=0;

printf("MOV %c,R%d\n",pos[4],index);

printf("%s %c,R%d\n",code[j],pos[2],index);

printf("MOV R%d,%c\n",index,pos[0]);

OUTPUT:

Enter ur 3 address code stmtz & # to terminate :

a=b+7
#

MOV 7,R0
ADD b,R0
MOV R0,a

Enter ur 3 address code stmtz & # to terminate :

a=5+c
#

MOV c,R0
ADD 5,R0
MOV R0,a

Result:

Thus the program to generate intermediate code was successfully implemented.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Implementation of Simple Code Optimization Techniques
Ex. No: 11
(Constant Folding., etc.)

Aim:

To Implement the Code Optimization techniques.


Description:

Code Optimization is an important phase of compiler. This phase optimizes the three
address codes into sequence of optimized three address codes.

Code Optimization
Intermediate code statements Optimized three address
codes(three address code)

Front end Code Optimizer Front end

Control flow Data Flow analysis Transformations


analysis

A Simple but effective technique for locally improving the target code is peephole
optimization,
 A method for trying to improve the performance of the target program
 By examining a short sequence of target instructions and replacing these instructions by a
shorter or faster sequence whenever possible.
Characteristics of peephole optimization
1. Redundant instruction elimination
2. Flow of control information
3. Algebraic Simplification
4. Use of machine Idiom.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


Program:

ALGORITHM:

Step1: Start the program

Step2: Declare the necessary variables and functions

Step3: Get the number of productions

Step4: Generate the left side and right side of each productions

Step4: Eliminate the intermediate code for the given productions

Step5: Eliminate the dead codes which are not used and then the common
expression.

Step6: Print the optimized code

Step7: Stop the program

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 no of values");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left\t");
op[i].l=getche();
printf("right:\t");
scanf("%s",op[i].r);
}
printf("intermediate Code\n") ;
for(i=0;i<n;i++)
{
printf("%c=",op[i].l);

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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",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);
}
// duplicate production elimination
for(i=0;i<z;i++)
{
for(j=i+1;j<z;j++)
{

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory


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");
for(i=0;i<z;i++)
{
if(pr[i].l!='\0')
{
printf("%c=",pr[i].l);
printf("%s\n",pr[i].r);
}}
getch();
}

OUTPUT:

ENTER NO 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
AFTER DEAD CODE ELIMINATION
b=c+d
e=c+d
f=b+e
r=f
ELIMINATE COMMON EXPRESSION
b=c+b
b=c+d
f=b+b
r=f
OPTIMIZED CODE
b=c+d
f=b+b
r=f

Result:

Thus the implementation of code optimizer was successfully completed.

THE KAVERY ENGINEERING COLLEGE Principles of Compiler Design Laboratory

You might also like