Compiler-Design-Lab-Manual - 42 Pages
Compiler-Design-Lab-Manual - 42 Pages
Name: Reg.No:
Degree: B.E (Computer
and Engineering) Year: III Semester: V
Subject Code: CS3501
Subject Name: COMPILER DESIGN
BONAFIDE CERTIFICATE
Certified that this is the bonafide record of practical exercises done by
Register number
of V Semester B.E CSE in the CS3501 – Compiler Design during the academic year 2023-2024 (ODD).
Certified that this record has been submitted for the practical examination held on at JP
COLLEGE OF ENGINEERING, Ayikudy conducted by Anna University, Chennai.
INTRODUCTION:
A Symbol table is a data structure used by a language translator such as a compiler or interpreter,
where each identifier in a program’s source code is associated with information relating to its declaration
or appearance in the source Possible entries in a symbol table: Name: a string.
• Attribute:
1. Reserved word
2. Variable name
3. Type Name
4. Procedure name
5. Constant name
• Data type
• Scope information: where it can be used. Storage allocation
SYMBOL TABLE
#includecstdio.hS
#includecconio.hS
#includecmalloc.hS
#includecstring.hS
#includecmath.hS
#includecctype.hS void main()
{
int i=O,j=O,x=O,n,flag=O;
void *p,*add[15];
char ch,srch,b[15],d[15],c;
clrscr();
printf("expression terminated by $:");
while((c=getchar())!='$')
{
b[i]=c;i++;
}
n=i-1;
printf("given expression:");
i=O;
while(ic=n)
{
printf("%c",b[i]); i++;
}
printf("symbol table\n");
OUTPUT:
RESULT:
Thus the C program to implement the symbol table was executed and the output is verified.
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.Examplesof 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.
Consider this expression in the C programming language:Sum=3 + 2;
PROGRAM:
#include<stdio.h>
#include<conio.h
>
#include<ctype.h>
#include<string.h
> void main()
{
FILE *fi,*fo,*fop,*fk;
intflag=0,i=1;
char c,t,a[15],ch[15],file[20];
clrscr();
printf("\n Enter the File Name:");
scanf("%s",&file);
fi=fopen(file,"r");
fo=fopen("inter.c","w");
fop=fopen("oper.c","r");
fk=fopen("key.c","r");
c=getc(fi); while(!
feof(fi))
{
if(isalpha(c)||isdigit(c)||(c=='['||c==']'||c=='.'==1))
fputc(c,fo);
else
{ if(c=='\n')
fprintf(fo,"\t$\t");
else fprintf(fo,"\t%c\
t",c);
}
Input.C:
#include "stdio.h"
#include
"conio.h" void
main()
{
int a=10,b,c; a=b*c;
getch();
}
RESULT:
Thus the above program for developing the lexical the lexical analyzer and recognizing
the fewpattern s in C is executed successfully and the output is verified.
AIM:
INTRODUCTION:
THEORY:
A language for specifying lexical analyzer.
There is a wide range of tools for construction of lexical analyzer. The majority of
thesetools are based on regular expressions.
The one of the traditional tools of that kind is lex.
LEX:
The lex is used in the manner depicted. A specification of the lexical analyzer is
preferred by creating a program lex.1 in the lex language.
Then lex.1 is run through the lex compiler to produce a ‘c’ program lex.yy.c.
The program lex.yy.c consists of a tabular representation of a transition diagram
constructed from the regular expression of lex.1 together with a standard routine that uses
table of recognize leximes.
Lex.yy.c is run through the ‘C’ compiler to produce as object program a.out, which is the
lexical analyzer that transform as input stream into sequence of tokens.
LEX SOURCE:
PROGRAM:
(LEXICAL ANALYZER USING LEX TOOL)
#includecstdio.hS
#includecctype.hS
#includecconio.hS
#includecstring.hS
char vars[1OO][1OO];
int vcnt;
char input[1OOO],c;
char token[5O],tlen;
int state=O,pos=O,i=O,id;
char *getAddress(char str[])
{
for(i=O;icvcnt;i++)
if(strcmp(str,vars[i])==O)
return vars[i];
strcpy(vars[vcnt],str);
return vars[vcnt++];
}
int isrelop(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='%'||c=='^')
return 1;
OUTPUT:
RESULT:
Thus the program for the exercise on lexical analysis using lex has been successfully
executed andoutput is verified.
AIM :
INTRODUCTION :
YACC (yet another compiler) is a program designed to produce designed to compile a
LALRgrammar and to produce the source code of the synthetically analyses of the language
produced bythe grammar.
ALGORITHM :
1. Start the program.
PROGRAM:
#include<stdio.h>
#include<conio.h
> void main()
{
char s[5];
clrscr();
printf("\n Enter any operator:");
gets(s);
switch(s[0])
{
case'>':
if(s[1]=='=')
printf("\n Greater than or equal");
else
OUTPUT:
RESULT:
Thus the program for the exercise on the syntax using YACC has been executed
successfully and Output is verified.
AIM:
ALGORITHM:
1. Start the program.
2. Reading an expression.
3. Checking the validating of the given expression according to the rule using yacc .
4. Using expression rule print the result of the given values.
5. Stop the program.
PROGRAM :
variable_test.l
%{
/* This LEX program returns the tokens for the Expression */
#include "y.tab.h"
%}
%%
"int " {return INT;} "float" {return FLOAT;}
"double" {return DOUBLE;} [a-zA-Z]*[O-9]*{
printf("\nIdentifier is %s",yytext);
return ID;
}
return yytext[O];
\n return O;
int yywrap()
{
return 1;
}
variable_test.y
%{
#include
/* This YACC program is for recognising the Expression*/
%}
%token ID INT FLOAT DOUBLE
%% D; T L ;
L:L,ID |ID ;
T:INT |FLOAT |DOUBLE ;
%%
extern FILE *yyin; main(
OUTPUT:
RESULT:
Thus the program for the exercise on the syntax using YACC has been executed
successfully and Output is verified.
AIM:
To write a program for implementing a calculator for computing the given expression using
semantic rules of the YACC tool and LEX.
ALGORITHM:
1. A Yacc source program has three parts as follows:
Declarations %% translation rules %% supporting C routines
2. Declarations Section: This section contains entries that:
i. Include standard I/O header file.
ii. Define global variables.
iii. Define the list rule as the place to start processing.
iv. Define the tokens used by the parser. v. Define the operators and
their precedence.
3. Rules Section: The rules section defines the rules that parse the input stream.
Each rule of a grammar production and the associated semantic action.
4. Programs Section: The programs section contains the following subroutines.
Because these subroutines are included in this file, it is not necessary to use the
yacc library when processing this file.
5. Main- The required main program that calls the yyparse subroutine to start
the program.
6. yyerror(s) -This error-handling subroutine only prints a syntax error message.
7. yywrap -The wrap-up subroutine that returns a value of 1 when the end of input
occurs. The calc.lex file contains include statements for standard input and
output, as programmar file information if we use the -d flag with the yacc
command. The y.tab.h file contains definitions for the tokens that the parser
program uses.
8. calc.lex contains the rules to generate these tokens from the input stream.
PROGRAM:
%{
#include cstdio.hS
int op=O,i; float a,b;
%}
dig[O-9]+|([O-9]*)"."([O-9]+)
add "+"
sub "-"mul"*
" div "/"
pow "^"ln \n
%%
OUTPUT:
Lex cal.l
Cc lex.yy.c-ll a.out
4*8
The result=32
RESULT:
Thus the program for the exercise on the syntax using YACC has been executed
Successfully and Output is verified.
AIM:
To write a C program for implementing type checking for given expression.
ALGORITHM:
The type analysis and type checking is an important activity done in the semantic
analysis phase. The need for type checking is
1. To detect the errors arising in the expression due to incompatible operand.
2. To generate intermediate code for expressions due to incompatible operand.
ALGORITHM:
1. Start a program.
2. Include all the header files.
3. Initialize all the functions and variables.
4. Get the expression from the user and separate into the tokens.
5. After separation, specify the identifiers, operators and number.
6. Print the output.
7. Stop the program.
PROGRAM:
( TYPE CHECKING)
#include cstdio.hS
charstr[5O],opstr[75];
int f[2][9]={2,3,4,4,4,O,6,6,O,1,1,3,3,5,5,O,5,O};
int col,col1,col2;
char c;
swt()
{
switch(c)
{
OUTPUT:
AIM:
INTRODUCTION:
Data flow analysis is a technique for gathering information about the possible set of value
calculated at various points in a computer program.
Control flow analysis can be represent by basic blocks. It depicts how th program control
is being passed among the blocks.
ALGORITHM:
AIM:
To 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.
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 knownas 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.
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
PROGRAM:
(BACK END OF THE COMPILER)
#includecstdio.hS
#includecstdio.hS
#includecconio.hS
#includecstring.h
S void main()
{
char icode[1O][3O],str[2O],opr[1O];
int i=O;
clrscr();
printf("\n Enter the set of intermediate code (terminated by exit):\n");
do
{
scanf("%s",icode[i]);
}
while(strcmp(icode[i++],"exit")!=O);
printf("\n target code generation");
printf("\n************************");
i=O;
do
{
strcpy(str,icode[i]);
switch(str[3])
{
case '+': strcpy(opr,"ADD");
break;
case '-': strcpy(opr,"SUB");
break;
case '*':
strcpy(opr,"MUL");
break;
case '/': strcpy(opr,"DIV");
break;
}
OUTPUT:
RESULT:
Thus the program was implemented to the TAC has been successfully executed.
AIM:
INTRODUCTION:
For Example:
Do
{
item=1O;
value=value+item;
}
while(valuec1OO);
This code involves repeated assignment of the identifier item, which if weput this way:
item=1O; do
{
value=value+item;
}
while(valuec1OO);
Machine dependent optimization is done after the target code has been generated and when
the code is transformed according to the target machine architecture. It involves CPU registers and
may have absolute memory references rather than relative references. Machine- dependent
optimizers put efforts to take maximum advantage of memory hierarchy.
ALGORITHM:
PROGRAM:
(SIMPLE CODE OPTIMIZATION TECHNIQUE)
Before:
Using for :
#includeciostream.hS
#include cconio.hS
int main()
{
int i, n;
int
fact=1;
cout cc"\nEnter a number: " cin SSn;
for(i=n;iS=1;i--)
fact=fact *i;
coutcc"The factoral value is: "ccfact;
getch();
return 0;
}
Using do-while:
#includeciostream.hS
#includecconio.hS void main()
{
clrscr();int n,f;
f=1;
coutcc"Enter the number:\n";
cinSSn;
do
{
f=f*n
; n--;
}
while(nSO);
coutcc"The factorial value is:"ccf;
getch();
}
OUTPUT:
RESULT:
Thus the Simple Code optimization technique is successfully executed.